diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5fadf1e..0329c3d 100755 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,9 +16,18 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Run composer install + uses: php-actions/composer@v6 + with: + php_version: ${{ env.PHP_VERSION }} + working_dir: "." + args: --ignore-platform-reqs + command: install + dev: no + # Add plugin files to a root directory - name: Make plugin root directory - run: "mkdir $PLUGIN_NAME && mv -t ./$PLUGIN_NAME ./languages ./resources ./includes *.txt *.php && find ./${{env.PLUGIN_NAME}} -type f -exec chmod 0644 {} + && find ./${{env.PLUGIN_NAME}} -type d -exec chmod 0755 {} + && ls -lah" + run: "mkdir $PLUGIN_NAME && mv -t ./$PLUGIN_NAME ./languages ./resources ./includes ./vendor *.txt *.php && find ./${{env.PLUGIN_NAME}} -type f -exec chmod 0644 {} + && find ./${{env.PLUGIN_NAME}} -type d -exec chmod 0755 {} + && ls -lah" # Compact plugin as .zip - name: Archive Release @@ -36,7 +45,7 @@ jobs: uses: mathieudutour/github-tag-action@v6.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} - custom_tag: "1.7.0" + custom_tag: "1.8.0" # Generate new release - name: Generate new Release diff --git a/.gitignore b/.gitignore index 87e0f70..0b26fda 100755 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.devcontainer/devcontainer.json node_modules sftp.json +vendor diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a71443..7fc009d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.8.0 - 10/05/2024 +* Adição de compatibilidade com block-based checkout; +* Adição de banner de hospedagem para Wordpress; +* Adição de campos obrigatórios para as credenciais de cartão de crédito e débito; +* Melhoria nos tratamentos de erros; + # 1.7.0 - 25/03/2024 * Correção de bug de carregamento de script do 3DS na opção cartão de débito; * Adição de lógica para lidar com respostas da API quando o código de retorno é "GF"; diff --git a/README.txt b/README.txt index 58f39d4..6c31652 100755 --- a/README.txt +++ b/README.txt @@ -4,7 +4,7 @@ Donate link: https://www.linknacional.com.br/wordpress/woocommerce/cielo/ Tags: woocommerce, payment, paymethod, card, credit Requires at least: 5.7 Tested up to: 6.5 -Stable tag: 1.7.0 +Stable tag: 1.8.0 Requires PHP: 7.2 License: GPLv3 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -72,6 +72,13 @@ Payment Gateway for Cielo API on WooCommerce plugin is dependent on WooCommerce == Changelog == += 1.8.0 = +**10/05/2024** +* Added support for block-based checkout; +* Addition of hosting banner for Wordpress; +* Addition of mandatory fields for credit and debit card credentials; +* Improvement in error handling; + = 1.7.0 = **25/03/2024** * Fixed 3DS script loading bug in the debit card option; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..ff289d3 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "lkn/wc-gateway-cielo", + "type": "project", + "license": "Proprietary", + "autoload": { + "psr-4": { + "Lkn\\WCCieloPaymentGateway\\Includes\\": "includes/" + } + }, + "authors": [ + { + "name": "Link Nacional", + "email": "ticket@linknacional.com" + } + ], + "minimum-stability": "stable", + "require-dev": { + "phan/phan": "5.4.1" + }, + "require": {} +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..eb83618 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1742 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "57dc47e6c860d961a26cb0bdbf6f20e0", + "packages": [], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.3", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8", + "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-03-19T10:26:25+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255", + "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-03-26T18:29:49+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/6a965617cf484355048ac6d2d3de7b6ec93abb16", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "support": { + "issues": "https://github.com/microsoft/tolerant-php-parser/issues", + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.1" + }, + "time": "2021-07-16T21:28:12+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.4.1", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0", + "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.4.1" + }, + "time": "2024-01-31T06:18:54+00:00" + }, + { + "name": "phan/phan", + "version": "5.4.1", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "fef40178a952bcfcc3f69b76989dd613c3d5c759" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/fef40178a952bcfcc3f69b76989dd613c3d5c759", + "reference": "fef40178a952bcfcc3f69b76989dd613c3d5c759", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4|^2.0|^3.0", + "composer/xdebug-handler": "^2.0|^3.0", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "0.1.1", + "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", + "php": "^7.2.0|^8.0.0", + "sabre/event": "^5.1.3", + "symfony/console": "^3.2|^4.0|^5.0|^6.0", + "symfony/polyfill-mbstring": "^1.11.0", + "symfony/polyfill-php80": "^1.20.0", + "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.", + "ext-var_representation": "Suggested for converting values to strings in issue messages" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static" + ], + "support": { + "issues": "https://github.com/phan/phan/issues", + "source": "https://github.com/phan/phan/tree/5.4.1" + }, + "time": "2022-08-26T00:49:07+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/298d2febfe79d03fe714eb871d5538da55205b1a", + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.0" + }, + "time": "2024-04-09T21:13:58+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "153ae662783729388a584b4361f2545e4d841e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" + }, + "time": "2024-02-23T11:10:43+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.28.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.28.0" + }, + "time": "2024-04-03T18:51:33+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d7da22897125d34d7eddf7977758191c06a74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", + "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2021-11-04T06:51:17+00:00" + }, + { + "name": "symfony/console", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "a170e64ae10d00ba89e2acbb590dc2e54da8ad8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a170e64ae10d00ba89e2acbb590dc2e54da8ad8f", + "reference": "a170e64ae10d00ba89e2acbb590dc2e54da8ad8f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e", + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.4.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-12-19T21:51:00+00:00" + }, + { + "name": "symfony/string", + "version": "v6.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/ffeb9591c61f65a68d47f77d12b83fa530227a69", + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:22:46+00:00" + }, + { + "name": "tysonandre/var_representation_polyfill", + "version": "0.1.3", + "source": { + "type": "git", + "url": "https://github.com/TysonAndre/var_representation_polyfill.git", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/e9116c2c352bb0835ca428b442dde7767c11ad32", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.2.0|^8.0.0" + }, + "provide": { + "ext-var_representation": "*" + }, + "require-dev": { + "phan/phan": "^5.4.1", + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-var_representation": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.3-dev" + } + }, + "autoload": { + "files": [ + "src/var_representation.php" + ], + "psr-4": { + "VarRepresentation\\": "src/VarRepresentation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + } + ], + "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export", + "keywords": [ + "var_export", + "var_representation" + ], + "support": { + "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.3" + }, + "time": "2022-08-31T12:59:22+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/includes/LknIntegrationRedeForWoocommerceWcCieloCreditBlocks.php b/includes/LknIntegrationRedeForWoocommerceWcCieloCreditBlocks.php new file mode 100644 index 0000000..7b4d120 --- /dev/null +++ b/includes/LknIntegrationRedeForWoocommerceWcCieloCreditBlocks.php @@ -0,0 +1,59 @@ +settings = get_option( 'woocommerce_lkn_cielo_credit_settings', array() ); + $this->gateway = new LknWCGatewayCieloCredit(); + } + + public function is_active() { + return $this->gateway->is_available(); + } + + public function get_payment_method_script_handles() { + wp_register_script( + 'lkn_cielo_credit-blocks-integration', + plugin_dir_url( __FILE__ ) . '../resources/js/creditCard/lknCieloCredit.js', + array( + 'wc-blocks-registry', + 'wc-settings', + 'wp-element', + 'wp-html-entities', + 'wp-i18n', + ), + '1.0.0', + true + ); + if ( function_exists( 'wp_set_script_translations' ) ) { + wp_set_script_translations( 'lkn_cielo_credit-blocks-integration'); + } + + return array('lkn_cielo_credit-blocks-integration'); + } + + public function get_payment_method_data() { + return array( + 'title' => $this->gateway->title, + 'description' => $this->gateway->description, + 'activeInstallment' => $this->gateway->get_option('installment_payment'), + 'installmentLimit' => $this->gateway->get_option('installment_limit', 12), + 'totalCart' => $this->gateway->lknGetCartTotal(), + 'nonceCieloCredit' => wp_create_nonce( 'nonce_lkn_cielo_credit' ), + 'translations' => [ + 'cardNumber' => __('Card Number', 'lkn-wc-gateway-cielo'), + 'cardExpiryDate' => __('Expiry Date', 'lkn-wc-gateway-cielo'), + 'securityCode' => __('Security Code', 'lkn-wc-gateway-cielo'), + 'installments' => __('Installments', 'lkn-wc-gateway-cielo') + ] + ); + } +} +?> \ No newline at end of file diff --git a/includes/LknIntegrationRedeForWoocommerceWcCieloDebitBlocks.php b/includes/LknIntegrationRedeForWoocommerceWcCieloDebitBlocks.php new file mode 100644 index 0000000..63d724b --- /dev/null +++ b/includes/LknIntegrationRedeForWoocommerceWcCieloDebitBlocks.php @@ -0,0 +1,67 @@ +settings = get_option( 'woocommerce_lkn_cielo_debit_settings', array() ); + $this->gateway = new LknWCGatewayCieloDebit(); + } + + public function is_active() { + return $this->gateway->is_available(); + } + + public function get_payment_method_script_handles() { + wp_register_script( + 'lkn_cielo_debit-blocks-integration', + plugin_dir_url( __FILE__ ) . '../resources/js/debitCard/lknCieloDebit.js', + array( + 'wc-blocks-registry', + 'wc-settings', + 'wp-element', + 'wp-html-entities', + 'wp-i18n', + ), + '1.0.0', + true + ); + if ( function_exists( 'wp_set_script_translations' ) ) { + wp_set_script_translations( 'lkn_cielo_debit-blocks-integration'); + } + + return array('lkn_cielo_debit-blocks-integration'); + } + + public function get_payment_method_data() { + if ($this->gateway->get_option('env') == 'sandbox') { + $dirScriptConfig3DS = LKN_WC_GATEWAY_CIELO_URL . 'resources/js/debitCard/lkn-dc-script-sdb.js'; + } else { + $dirScriptConfig3DS = LKN_WC_GATEWAY_CIELO_URL . 'resources/js/debitCard/lkn-dc-script-prd.js'; + } + + return array( + 'title' => $this->gateway->title, + 'description' => $this->gateway->description, + 'accessToken' => $this->gateway->generate_debit_auth_token(), + 'url' => get_page_link(), + 'orderNumber' => uniqid(), + 'dirScript3DS' => LKN_WC_GATEWAY_CIELO_URL . 'resources/js/debitCard/BP.Mpi.3ds20.min.js', + 'dirScriptConfig3DS' => $dirScriptConfig3DS, + 'totalCart' => $this->gateway->lknGetCartTotal(), + 'nonceCieloDebit' => wp_create_nonce( 'nonce_lkn_cielo_debit' ), + 'translations' => [ + 'cardNumber' => __('Card Number', 'lkn-wc-gateway-cielo'), + 'cardExpiryDate' => __('Expiry Date', 'lkn-wc-gateway-cielo'), + 'securityCode' => __('Security Code', 'lkn-wc-gateway-cielo'), + ] + ); + } +} +?> \ No newline at end of file diff --git a/includes/class-lkn-wc-gateway-cielo-credit.php b/includes/LknWCGatewayCieloCredit.php old mode 100755 new mode 100644 similarity index 88% rename from includes/class-lkn-wc-gateway-cielo-credit.php rename to includes/LknWCGatewayCieloCredit.php index d2834a8..b29f0da --- a/includes/class-lkn-wc-gateway-cielo-credit.php +++ b/includes/LknWCGatewayCieloCredit.php @@ -1,4 +1,12 @@ __('This controls the title which the user sees during checkout.', 'lkn-wc-gateway-cielo'), 'default' => __('Credit card', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'description' => array( 'title' => __('Description', 'lkn-wc-gateway-cielo'), @@ -156,18 +167,27 @@ public function init_form_fields(): void { 'default' => __('Payment processed by Cielo API 3.0', 'lkn-wc-gateway-cielo'), 'description' => __('Payment method description that the customer will see on your checkout.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'merchant_id' => array( 'title' => __('Merchant Id', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo API 3.0 credentials.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'merchant_key' => array( 'title' => __('Merchant Key', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo API 3.0 credentials.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'invoiceDesc' => array( 'title' => __('Invoice Description', 'lkn-wc-gateway-cielo'), @@ -227,6 +247,7 @@ public function payment_fields(): void { $noLoginCheckout = isset($_GET['pay_for_order']) ? sanitize_text_field($_GET['pay_for_order']) : 'false'; $installmentLimit = $this->get_option('installment_limit', 12); $installments = array(); + $nonce = wp_create_nonce( 'nonce_lkn_cielo_credit'); for ($c = 1; $c <= $installmentLimit; ++$c) { $interest = preg_replace('/\D/', '', $this->get_option($c . 'x', 0)); @@ -245,45 +266,94 @@ public function payment_fields(): void { echo wpautop(wp_kses_post($this->description)); ?> -
+
id); ?> +
-
-
-
- - - - + + + +
-
'fail', + 'redirect' => '', + ); + } + $order = wc_get_order($order_id); + // Card parameters $cardNum = preg_replace('/\s/', '', sanitize_text_field($_POST['lkn_ccno'])); $cardExpSplit = explode('/', preg_replace('/\s/', '', sanitize_text_field($_POST['lkn_cc_expdate']))); @@ -428,7 +505,7 @@ public function process_payment($order_id) { 'MerchantKey' => $merchantSecret, ); - $args['body'] = json_encode(array( + $body = array( 'MerchantOrderId' => $merchantOrderId, 'Payment' => array( 'Type' => 'CreditCard', @@ -445,7 +522,11 @@ public function process_payment($order_id) { 'Brand' => $provider, ), ), - )); + ); + + $body = apply_filters('lkn_wc_cielo_process_body', $body, $_POST, $order_id); + + $args['body'] = wp_json_encode($body); $response = wp_remote_post($url . '1/sales', $args); @@ -503,7 +584,7 @@ public function process_payment($order_id) { } if (isset($responseDecoded->Payment->ReturnCode) && 'GF' == $responseDecoded->Payment->ReturnCode) { // Error GF detected, notify site admin - $error_message = "Return Code: " . $responseDecoded->Payment->ReturnCode . '. Return Message: ' . $responseDecoded->Payment->ReturnMessage . '.' . __('Please contact Cielo for further assistance.', 'lkn-wc-gateway-cielo'); + $error_message = "Return Code: " . $responseDecoded->Payment->ReturnCode . '. Return Message: ' . $responseDecoded->Payment->ReturnMessage . '.' . __('Please contact Cielo for further assistance.', 'lkn-wc-gateway-cielo'); //wp_mail(get_option('admin_email'), 'Erro na transação Cielo', $error_message); // Registrar a mensagem de erro em um arquivo de log @@ -516,10 +597,19 @@ public function process_payment($order_id) { if ('yes' === $debug) { $this->log->log('error', var_export($response, true), array('source' => 'woocommerce-cielo-credit')); } - - $message = __('Order payment failed. Make sure your credit card is valid.', 'lkn-wc-gateway-cielo'); - - throw new Exception($message); + } + + /** + * Calculate the total value of items in the WooCommerce cart. + */ + public static function lknGetCartTotal() { + $cart_items = WC()->cart->get_cart(); + $total = 0; + foreach ($cart_items as $cart_item_key => $cart_item) { + $product = $cart_item['data']; + $total += $product->get_price() * $cart_item['quantity']; + } + return $total; } /** @@ -688,8 +778,6 @@ private function get_card_provider($cardNumber) { $brand = ''; $brand = apply_filters('lkn_wc_cielo_get_card_brand', $brand, $cardNumber); - $this->log->log('error', 'GET BRAND CIELO CARD: ' . var_export($brand, true), array('source' => 'woocommerce-cielo-credit')); - if (empty($brand)) { // Stores regex for Card Bin Tests $bin = array( diff --git a/includes/class-lkn-wc-gateway-cielo-debit.php b/includes/LknWCGatewayCieloDebit.php old mode 100755 new mode 100644 similarity index 79% rename from includes/class-lkn-wc-gateway-cielo-debit.php rename to includes/LknWCGatewayCieloDebit.php index 08bc4ab..27f1dd3 --- a/includes/class-lkn-wc-gateway-cielo-debit.php +++ b/includes/LknWCGatewayCieloDebit.php @@ -1,4 +1,12 @@ __('This controls the title which the user sees during checkout.', 'lkn-wc-gateway-cielo'), 'default' => __('Debit card', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'description' => array( 'title' => __('Description', 'lkn-wc-gateway-cielo'), @@ -161,48 +172,72 @@ public function init_form_fields(): void { 'default' => __('Payment processed by Cielo API 3.0', 'lkn-wc-gateway-cielo'), 'description' => __('Payment method description that the customer will see on your checkout.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'client_id' => array( 'title' => __('Client Id', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo 3DS 2.0 registration required (ask for eCommerce support).', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'client_secret' => array( 'title' => __('Client Secret', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo 3DS 2.0 registration required (ask for eCommerce support).', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'merchant_id' => array( 'title' => __('Merchant Id', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo API 3.0 credentials.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'merchant_key' => array( 'title' => __('Merchant Key', 'lkn-wc-gateway-cielo'), 'type' => 'password', 'description' => __('Cielo API 3.0 credentials.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'establishment_code' => array( 'title' => __('Establishment Code', 'lkn-wc-gateway-cielo'), 'type' => 'text', 'description' => __('Establishment code for Cielo 3DS E-Commerce 3.0.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'merchant_name' => array( 'title' => __('Merchant Name', 'lkn-wc-gateway-cielo'), 'type' => 'text', 'description' => __('Establishment name registered on Cielo 3DS E-Commerce 3.0.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'mcc' => array( 'title' => __('Establishment Category Code', 'lkn-wc-gateway-cielo'), 'type' => 'text', 'description' => __('Establishment category code for Cielo 3DS E-Commerce 3.0.', 'lkn-wc-gateway-cielo'), 'desc_tip' => true, + 'custom_attributes' => array( + 'required' => 'required' + ) ), 'invoiceDesc' => array( 'title' => __('Invoice Description', 'lkn-wc-gateway-cielo'), @@ -251,50 +286,66 @@ public function init_form_fields(): void { * Generate Cielo API 3.0 in auth token. */ public function generate_debit_auth_token() { - $env = $this->get_option('env'); - $clientId = $this->get_option('client_id'); - $clientSecret = $this->get_option('client_secret'); - $url = ('sandbox' === $env) ? 'https://mpisandbox.braspag.com.br/v2/auth/token/' : 'https://mpi.braspag.com.br/v2/auth/token/'; + try { + $env = $this->get_option('env'); + $clientId = $this->get_option('client_id'); + $clientSecret = $this->get_option('client_secret'); + $url = ('sandbox' === $env) ? 'https://mpisandbox.braspag.com.br/v2/auth/token/' : 'https://mpi.braspag.com.br/v2/auth/token/'; - $establishmentCode = $this->get_option('establishment_code'); - $merchantName = $this->get_option('merchant_name'); - $mcc = $this->get_option('mcc'); - $debug = $this->get_option('debug'); + $establishmentCode = $this->get_option('establishment_code'); + $merchantName = $this->get_option('merchant_name'); + $mcc = $this->get_option('mcc'); + $debug = $this->get_option('debug'); - $authCode = base64_encode($clientId . ':' . $clientSecret); + $authCode = base64_encode($clientId . ':' . $clientSecret); - $args['headers'] = array( - 'Content-Type' => 'application/json', - 'Authorization' => 'Basic ' . $authCode, - ); + $args['headers'] = array( + 'Content-Type' => 'application/json', + 'Authorization' => 'Basic ' . $authCode, + ); - $args['body'] = json_encode(array( - 'EstablishmentCode' => $establishmentCode, - 'MerchantName' => $merchantName, - 'MCC' => $mcc, - )); + $args['body'] = wp_json_encode(array( + 'EstablishmentCode' => $establishmentCode, + 'MerchantName' => $merchantName, + 'MCC' => $mcc, + )); - $response = wp_remote_post($url, $args); + $response = wp_remote_post($url, $args); - if (is_wp_error($response)) { - if ('yes' === $debug) { - $this->log->log('error', var_export($response->get_error_messages(), true), array('source' => 'woocommerce-cielo-debit')); - } + if (is_wp_error($response)) { + if ('yes' === $debug) { + $this->log->log('error', var_export($response->get_error_messages(), true), array('source' => 'woocommerce-cielo-debit')); + } - $message = __('Auth token generation failed.', 'lkn-wc-gateway-cielo'); + $message = __('Auth token generation failed.', 'lkn-wc-gateway-cielo'); - throw new Exception($message); - } - $responseDecoded = json_decode($response['body']); + throw new Exception($message); + } + $responseDecoded = json_decode($response['body']); - if (isset($responseDecoded->access_token)) { - return $responseDecoded->access_token; - } - if ('yes' === $debug) { - $this->log->log('error', var_export($response, true), array('source' => 'woocommerce-cielo-debit')); + if (isset($responseDecoded->access_token)) { + return $responseDecoded->access_token; + } + } catch ( Exception $e ) { + $this->add_error( $e->getMessage() ); + if ('yes' === $debug) { + $this->log->log('error', var_export($response, true), array('source' => 'woocommerce-cielo-debit')); + } + return false; } + } - return false; + /** + * Calculate the total value of items in the WooCommerce cart. + */ + public static function lknGetCartTotal() { + $cart_items = WC()->cart->get_cart(); + $total = 0; + foreach ($cart_items as $cart_item_key => $cart_item) { + $product = $cart_item['data']; + $total += $product->get_price() * $cart_item['quantity']; + } + return $total; } /** @@ -304,6 +355,7 @@ public function payment_fields(): void { $total_cart = number_format($this->get_order_total(), 2, '', ''); $accessToken = $this->generate_debit_auth_token(); $url = get_page_link(); + $nonce = wp_create_nonce( 'nonce_lkn_cielo_debit'); if (isset($_GET['pay_for_order'])) { $order_id = wc_get_order_id_by_order_key(sanitize_text_field($_GET['key'])); @@ -313,53 +365,173 @@ public function payment_fields(): void { echo wpautop(wp_kses_post($this->description)); ?> -
- - - - - - - - - - - - - - - - - - - +
+ + + + + + + + + + + + + + + + + + + + id); ?>
-
-
-
@@ -406,6 +578,13 @@ public function validate_fields() { * @return array */ public function process_payment($order_id) { + if ( ! wp_verify_nonce($_POST['nonce_lkn_cielo_debit'], 'nonce_lkn_cielo_debit')) { + return array( + 'result' => 'fail', + 'redirect' => '', + ); + } + $order = wc_get_order($order_id); // Card parameters @@ -488,7 +667,7 @@ public function process_payment($order_id) { 'RequestId' => uniqid(), ); - $args['body'] = json_encode(array( + $body = array( 'MerchantOrderId' => $merchantOrderId, 'Customer' => array( 'Name' => $cardName, @@ -513,7 +692,11 @@ public function process_payment($order_id) { 'dataonly' => true, ), ), - )); + ); + + $body = apply_filters('lkn_wc_cielo_process_body', $body, $_POST, $order_id); + + $args['body'] = wp_json_encode($body); } else { if (empty($cavv)) { $message = __('Invalid Cielo 3DS 2.0 authentication.', 'lkn-wc-gateway-cielo'); @@ -533,7 +716,7 @@ public function process_payment($order_id) { 'RequestId' => uniqid(), ); - $args['body'] = json_encode(array( + $body = array( 'MerchantOrderId' => $merchantOrderId, 'Customer' => array( 'Name' => $cardName, @@ -560,7 +743,11 @@ public function process_payment($order_id) { 'ReferenceId' => $refId, ), ), - )); + ); + + $body = apply_filters('lkn_wc_cielo_process_body', $body, $_POST, $order_id); + + $args['body'] = wp_json_encode($body); } $response = wp_remote_post($url . '1/sales', $args); diff --git a/lkn-wc-gateway-cielo.php b/lkn-wc-gateway-cielo.php index a1a3024..fdf5965 100755 --- a/lkn-wc-gateway-cielo.php +++ b/lkn-wc-gateway-cielo.php @@ -4,7 +4,7 @@ * Plugin URI: https://www.linknacional.com.br/wordpress/woocommerce/cielo/ * Description: Adds the Cielo API 3.0 Payments gateway to your WooCommerce website. * - * Version: 1.7.0 + * Version: 1.8.0 * * Author: Link Nacional * Author URI: https://linknacional.com.br @@ -17,6 +17,13 @@ * License URI: http://www.gnu.org/licenses/gpl-3.0.html */ +use Lkn\WCCieloPaymentGateway\Includes\LknIntegrationRedeForWoocommerceWcCieloCreditBlocks; +use Lkn\WCCieloPaymentGateway\Includes\LknIntegrationRedeForWoocommerceWcCieloDebitBlocks; +use Lkn\WCCieloPaymentGateway\Includes\LknWCGatewayCieloCredit; +use Lkn\WCCieloPaymentGateway\Includes\LknWCGatewayCieloDebit; + +require_once __DIR__ . '/vendor/autoload.php'; + // Exit if accessed directly. if ( ! defined('ABSPATH')) { exit; @@ -27,7 +34,7 @@ * * @class Lkn_WC_Cielo_Payment */ -final class Lkn_WC_Cielo_Payment { +final class LknWCCieloPayment { /** * Show plugin dependency notice. * @@ -75,6 +82,9 @@ public static function init(): void { // Load text domains add_action('init', array(__CLASS__, 'lkn_wc_gateway_cielo_load_textdomain')); + add_action('beforewoocommerce_init', array(__CLASS__, 'wcEditorBlocksActive')); + add_action('woocommerce_blocks_payment_method_type_registration', array(__CLASS__, 'wcEditorBlocksAddPaymentMethod')); + // Cielo Payments gateway class. add_action('plugins_loaded', array(__CLASS__, 'includes'), 0); @@ -91,10 +101,29 @@ public static function init(): void { add_action('woocommerce_order_details_after_order_table', array(__CLASS__, 'order_details_after_order_table'), 10, 1); } - /** + public static function wcEditorBlocksActive(): void { + if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) { + Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( + 'cart_checkout_blocks', + __FILE__, + true + ); + } + } + + public static function wcEditorBlocksAddPaymentMethod(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry): void { + if ( ! class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' )) { + return; + } + + $payment_method_registry->register( new LknIntegrationRedeForWoocommerceWcCieloCreditBlocks() ); + $payment_method_registry->register( new LknIntegrationRedeForWoocommerceWcCieloDebitBlocks() ); + } + + /** * Check plugin environment. * - * @return bool|null + * @return bool|null * * @since */ @@ -169,8 +198,8 @@ public static function lkn_wc_gateway_cielo_load_textdomain(): void { * @param mixed $gateways */ public static function add_gateway($gateways) { - $gateways[] = 'Lkn_WC_Gateway_Cielo_Credit'; - $gateways[] = 'Lkn_WC_Gateway_Cielo_Debit'; + $gateways[] = new LknWCGatewayCieloCredit(); + $gateways[] = new LknWCGatewayCieloDebit(); return $gateways; } @@ -179,15 +208,8 @@ public static function add_gateway($gateways) { * Plugin includes. */ public static function includes(): void { - Lkn_WC_Cielo_Payment::setup_constants(); - Lkn_WC_Cielo_Payment::check_environment(); - - // Make the Lkn_WC_Gateway_Cielo_Credit class available. - if (class_exists('WC_Payment_Gateway')) { - require_once 'includes/class-lkn-wc-gateway-cielo-credit.php'; - - require_once 'includes/class-lkn-wc-gateway-cielo-debit.php'; - } + LknWCCieloPayment::setup_constants(); + LknWCCieloPayment::check_environment(); } /** @@ -266,7 +288,7 @@ public static function email_order_meta_fields($fields, $sent_to_admin, $order) private static function setup_constants(): void { // Defines addon version number for easy reference. if ( ! defined('LKN_WC_CIELO_VERSION')) { - define('LKN_WC_CIELO_VERSION', '1.7.0'); + define('LKN_WC_CIELO_VERSION', '1.8.0'); } if ( ! defined('LKN_WC_CIELO_TRANSLATION_PATH')) { define('LKN_WC_CIELO_TRANSLATION_PATH', plugin_dir_path(__FILE__) . 'languages/'); @@ -277,10 +299,13 @@ private static function setup_constants(): void { if ( ! defined('LKN_WC_GATEWAY_CIELO_DIR')) { define('LKN_WC_GATEWAY_CIELO_DIR', plugin_dir_path(__FILE__)); } + if ( ! defined('LKN_WC_GATEWAY_CIELO_URL')) { + define('LKN_WC_GATEWAY_CIELO_URL', plugin_dir_url(__FILE__)); + } if ( ! defined('LKN_WC_GATEWAY_CIELO_MIN_WC_VERSION')) { define('LKN_WC_GATEWAY_CIELO_MIN_WC_VERSION', '5.0.0'); } } } -Lkn_WC_Cielo_Payment::init(); +LknWCCieloPayment::init(); diff --git a/resources/js/admin/lkn-wc-gateway-admin.js b/resources/js/admin/lkn-wc-gateway-admin.js index b396a2d..abf8b13 100755 --- a/resources/js/admin/lkn-wc-gateway-admin.js +++ b/resources/js/admin/lkn-wc-gateway-admin.js @@ -1,11 +1,25 @@ const adminPage = lknFindGetParameter('section') if (adminPage && (adminPage === 'lkn_cielo_credit' || adminPage === 'lkn_cielo_debit')) { - const wcForm = document.getElementsByClassName('form-table')[0] + const wcFormDiv = document.getElementById('mainform') + + const noticeDiv = document.createElement('div') + noticeDiv.setAttribute('style', 'background-color: #fcf9e8;color: #646970;border: solid 1px #d3d3d3;border-left: 4px #dba617 solid;font-size: 16px;margin-top: 10px;') + noticeDiv.setAttribute('id', 'lkn-cielo-hosting-notice') + + noticeDiv.innerHTML = 'Parabéns! Você ganhou uma hospedagem WooCommerce grátis por 12 meses. Solicite agora!' + + wcFormDiv.append(noticeDiv) +} + +if (adminPage && (adminPage === 'lkn_cielo_credit' || adminPage === 'lkn_cielo_debit')) { + const wcForm = document.getElementById('mainform') const noticeDiv = document.createElement('div') noticeDiv.setAttribute('style', 'padding: 10px 5px;background-color: #fcf9e8;color: #646970;border: solid 1px lightgrey;border-left-color: #dba617;border-left-width: 4px;font-size: 14px;min-width: 625px;margin-top: 10px;') + noticeDiv.setAttribute('id', 'lkn-cielo-pro-notice') noticeDiv.innerHTML = '
Obtenha novas funcionalidades com Cielo API Pro
' + + 'Conheça e compre o plugin PRO' + '
    ' + '
  • Captura manual da transação/pedido
  • ' + '
  • Ferramenta de reembolso total ou parcial
  • ' + @@ -14,8 +28,7 @@ if (adminPage && (adminPage === 'lkn_cielo_credit' || adminPage === 'lkn_cielo_d '
  • Habilita o parcelamento em até 18x (Visa, Elo, Amex, Hipercard, Mastercard)
  • ' + '
  • Configuração de quantidade máxima de parcelas
  • ' + '
  • Compatibilidade com a opção de Checkout do Elementor para WooCommerce
  • ' + - '
' + - 'Conheça e compre o plugin PRO' + '' wcForm.append(noticeDiv) } diff --git a/resources/js/creditCard/lknCieloCredit.js b/resources/js/creditCard/lknCieloCredit.js new file mode 100644 index 0000000..6ec47f9 --- /dev/null +++ b/resources/js/creditCard/lknCieloCredit.js @@ -0,0 +1,170 @@ +const settings_creditCard = window.wc.wcSettings.getSetting('lkn_cielo_credit_data', {}); +const label_creditCard = window.wp.htmlEntities.decodeEntities(settings_creditCard.title); +const activeInstallment = window.wp.htmlEntities.decodeEntities(settings_creditCard.activeInstallment); +const totalCartCredit = window.wp.htmlEntities.decodeEntities(settings_creditCard.totalCart); +const installmentLimit = window.wp.htmlEntities.decodeEntities(settings_creditCard.installmentLimit); +const translations = settings_creditCard.translations; +const nonceCieloCredit = settings_creditCard.nonceCieloCredit; +const Content_cieloCredit = props => { + const [options, setOptions] = window.wp.element.useState([]); + const { + eventRegistration, + emitResponse + } = props; + const { + onPaymentSetup + } = eventRegistration; + const [creditObject, setCreditObject] = window.wp.element.useState({ + lkn_ccno: '', + lkn_cc_expdate: '', + lkn_cc_cvc: '', + lkn_cc_installments: '1' // Definir padrão como 1 parcela + }); + + const formatCreditCardNumber = value => { + if (value?.length > 19) return creditObject.lkn_ccno; + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, ''); + // Adiciona espaços a cada quatro dígitos + const formattedValue = cleanedValue?.replace(/(.{4})/g, '$1 ')?.trim(); + return formattedValue; + }; + const updateCreditObject = (key, value) => { + switch (key) { + case 'lkn_cc_expdate': + if (value.length > 7) return; + + // Verifica se o valor é uma data válida (MM/YY) + const isValidDate = /^\d{2}\/\d{2}$/.test(value); + if (!isValidDate) { + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, ''); + let formattedValue = cleanedValue?.replace(/^(.{2})/, '$1 / ')?.trim(); + + // Se o tamanho da string for 5, remove o espaço e a barra adicionados anteriormente + if (formattedValue.length === 4) { + formattedValue = formattedValue.replace(/\s\//, ''); + } + + // Atualiza o estado + setCreditObject({ + ...creditObject, + [key]: formattedValue + }); + } + return; + case 'lkn_cc_cvc': + if (value.length > 4) return; + break; + default: + break; + } + setCreditObject({ + ...creditObject, + [key]: value + }); + }; + const wcComponents = window.wc.blocksComponents; + window.wp.element.useEffect(() => { + const installmentMin = 5; + // Verifica se 'activeInstallment' é 'yes' e o valor total é maior que 10 + if (activeInstallment === 'yes' && totalCartCredit > 10) { + const maxInstallments = installmentLimit; // Limita o parcelamento até 12 vezes, deixei fixo para teste + + for (let index = 1; index <= maxInstallments; index++) { + const installmentAmount = (totalCartCredit / index).toLocaleString('pt-BR', { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }); + const nextInstallmentAmount = totalCartCredit / index; + if (nextInstallmentAmount < installmentMin) { + break; + } + setOptions(prevOptions => [...prevOptions, { + key: index, + label: `${index}x de R$ ${installmentAmount} sem juros` + }]); + } + } else { + setOptions(prevOptions => [...prevOptions, { + key: '1', + label: `1x de R$ ${totalCartCredit} (à vista)` + }]); + } + }, []); + window.wp.element.useEffect(() => { + const unsubscribe = onPaymentSetup(async () => { + // Verifica se todos os campos do creditObject estão preenchidos + const allFieldsFilled = Object.values(creditObject).every(field => field.trim() !== ''); + if (allFieldsFilled) { + return { + type: emitResponse.responseTypes.SUCCESS, + meta: { + paymentMethodData: { + lkn_ccno: creditObject.lkn_ccno, + lkn_cc_expdate: creditObject.lkn_cc_expdate, + lkn_cc_cvc: creditObject.lkn_cc_cvc, + lkn_cc_installments: creditObject.lkn_cc_installments, + nonce_lkn_cielo_credit: nonceCieloCredit + } + } + }; + } + return { + type: emitResponse.responseTypes.ERROR, + message: 'Por favor, preencha todos os campos.' + }; + }); + + // Cancela a inscrição quando este componente é desmontado. + return () => { + unsubscribe(); + }; + }, [creditObject, emitResponse.responseTypes.ERROR, emitResponse.responseTypes.SUCCESS, onPaymentSetup]); + return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("h4", null, "Pagamento processado pela Cielo API 3.0")), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_ccno", + label: translations.cardNumber, + value: creditObject.lkn_ccno, + onChange: value => { + updateCreditObject('lkn_ccno', formatCreditCardNumber(value)); + } + }), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_cc_expdate", + label: translations.cardExpiryDate, + value: creditObject.lkn_cc_expdate, + onChange: value => { + updateCreditObject('lkn_cc_expdate', value); + } + }), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_cc_cvc", + label: translations.securityCode, + value: creditObject.lkn_cc_cvc, + onChange: value => { + updateCreditObject('lkn_cc_cvc', value); + } + }), /*#__PURE__*/React.createElement("div", { + style: { + marginBottom: '20px' + } + }), activeInstallment === 'yes' && /*#__PURE__*/React.createElement(wcComponents.SortSelect, { + id: "lkn_cc_installments", + label: translations.installments, + value: creditObject.lkn_cc_installments, + onChange: event => { + updateCreditObject('lkn_cc_installments', event.target.value); + }, + options: options + })); +}; +const Block_Gateway_Credit_Card = { + name: 'lkn_cielo_credit', + label: label_creditCard, + content: window.wp.element.createElement(Content_cieloCredit), + edit: window.wp.element.createElement(Content_cieloCredit), + canMakePayment: () => true, + ariaLabel: label_creditCard, + supports: { + features: settings_creditCard.supports + } +}; +window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway_Credit_Card); \ No newline at end of file diff --git a/resources/js/creditCard/lknCieloCredit.tsx b/resources/js/creditCard/lknCieloCredit.tsx new file mode 100644 index 0000000..97b7a08 --- /dev/null +++ b/resources/js/creditCard/lknCieloCredit.tsx @@ -0,0 +1,201 @@ +const settings_creditCard = window.wc.wcSettings.getSetting('lkn_cielo_credit_data', {}) +const label_creditCard = window.wp.htmlEntities.decodeEntities(settings_creditCard.title) +const activeInstallment = window.wp.htmlEntities.decodeEntities(settings_creditCard.activeInstallment) +const totalCartCredit = window.wp.htmlEntities.decodeEntities(settings_creditCard.totalCart) +const installmentLimit = window.wp.htmlEntities.decodeEntities(settings_creditCard.installmentLimit); +const translations = settings_creditCard.translations +const nonceCieloCredit = settings_creditCard.nonceCieloCredit; + +const Content_cieloCredit = (props) => { + const [options, setOptions] = window.wp.element.useState([]) + + const { eventRegistration, emitResponse } = props + const { onPaymentSetup } = eventRegistration + + const [creditObject, setCreditObject] = window.wp.element.useState({ + lkn_ccno: '', + lkn_cc_expdate: '', + lkn_cc_cvc: '', + lkn_cc_installments: '1', // Definir padrão como 1 parcela + }) + + const formatCreditCardNumber = value => { + if (value?.length > 19) return creditObject.lkn_ccno + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, '') + // Adiciona espaços a cada quatro dígitos + const formattedValue = cleanedValue?.replace(/(.{4})/g, '$1 ')?.trim() + return formattedValue + } + + const updateCreditObject = (key, value) => { + switch (key) { + case 'lkn_cc_expdate': + if (value.length > 7) return + + // Verifica se o valor é uma data válida (MM/YY) + const isValidDate = /^\d{2}\/\d{2}$/.test(value) + if (!isValidDate) { + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, '') + let formattedValue = cleanedValue?.replace(/^(.{2})/, '$1 / ')?.trim() + + // Se o tamanho da string for 5, remove o espaço e a barra adicionados anteriormente + if (formattedValue.length === 4) { + formattedValue = formattedValue.replace(/\s\//, '') + } + + // Atualiza o estado + setCreditObject({ + ...creditObject, + [key]: formattedValue + }) + } + return + case 'lkn_cc_cvc': + if (value.length > 4) return + break + default: + break + } + setCreditObject({ + ...creditObject, + [key]: value + }) + } + + const wcComponents = window.wc.blocksComponents + + window.wp.element.useEffect(() => { + const installmentMin = 5; + // Verifica se 'activeInstallment' é 'yes' e o valor total é maior que 10 + if (activeInstallment === 'yes' && totalCartCredit > 10) { + const maxInstallments = installmentLimit; // Limita o parcelamento até 12 vezes, deixei fixo para teste + + for (let index = 1; index <= maxInstallments; index++) { + const installmentAmount = (totalCartCredit / index).toLocaleString('pt-BR', { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }); + + const nextInstallmentAmount = totalCartCredit / (index); + + if (nextInstallmentAmount < installmentMin) { + break; + } + + setOptions(prevOptions => [ + ...prevOptions, + { key: index, label: `${index}x de R$ ${installmentAmount} sem juros` } + ]) + } + }else{ + setOptions(prevOptions => [ + ...prevOptions, + { key: '1', label: `1x de R$ ${totalCartCredit} (à vista)`} + ]) + } + },[]) + + window.wp.element.useEffect(() => { + const unsubscribe = onPaymentSetup(async () => { + // Verifica se todos os campos do creditObject estão preenchidos + const allFieldsFilled = Object.values(creditObject).every((field) => field.trim() !== ''); + + if (allFieldsFilled) { + return { + type: emitResponse.responseTypes.SUCCESS, + meta: { + paymentMethodData: { + lkn_ccno: creditObject.lkn_ccno, + lkn_cc_expdate: creditObject.lkn_cc_expdate, + lkn_cc_cvc: creditObject.lkn_cc_cvc, + lkn_cc_installments: creditObject.lkn_cc_installments, + nonce_lkn_cielo_credit: nonceCieloCredit, + }, + }, + }; + } + + return { + type: emitResponse.responseTypes.ERROR, + message: 'Por favor, preencha todos os campos.', + }; + + }); + + // Cancela a inscrição quando este componente é desmontado. + return () => { + unsubscribe(); + }; + }, [creditObject, + emitResponse.responseTypes.ERROR, + emitResponse.responseTypes.SUCCESS, + onPaymentSetup + ]); + + return ( + <> +
+

Pagamento processado pela Cielo API 3.0

+
+ + { + updateCreditObject('lkn_ccno', formatCreditCardNumber(value)) + }} + /> + + { + updateCreditObject('lkn_cc_expdate', value) + }} + /> + + { + updateCreditObject('lkn_cc_cvc', value) + }} + /> + +
+ + {activeInstallment === 'yes' && ( + { + updateCreditObject('lkn_cc_installments', event.target.value) + }} + options={options} + /> + )} + + )} + + +const Block_Gateway_Credit_Card = { + name: 'lkn_cielo_credit', + label: label_creditCard, + content: window.wp.element.createElement(Content_cieloCredit), + edit: window.wp.element.createElement(Content_cieloCredit), + canMakePayment: () => true, + ariaLabel: label_creditCard, + supports: { + features: settings_creditCard.supports + } +}; + +window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway_Credit_Card) + + diff --git a/resources/js/debitCard/BP.Mpi.3ds20.min.js b/resources/js/debitCard/BP.Mpi.3ds20.min.js new file mode 100644 index 0000000..a80c6c7 --- /dev/null +++ b/resources/js/debitCard/BP.Mpi.3ds20.min.js @@ -0,0 +1 @@ +function bpmpi_authenticate() { BP.Mpi.authenticate() } function bpmpi_load() { BP.Mpi.load() } var BP = function () { function e(e) { return document.getElementsByClassName(e).length > 0 } function r(r) { return e(r) ? document.getElementsByClassName(r)[0].value : null } function n(r, n) { return e(r) ? document.getElementsByClassName(r)[0].value : n } function i(e) { return e.replace("bpmpi_", "").replace(/\_/g, "") } function t(e) { return /\#/.test(e) } function o(e, r) { return e.replace(/\#/, r) } function a(e) { var r = i(e), n = r.split("#"); return { enumerable: n[0], field: n[1] } } function s() { var n = {}; for (var s in N) { var p = N[s]; if (t(p) === !1) { var c = i(p), u = r(p); u && (n[c] = r(p)) } else for (var d = 1, l = o(p, d); e(l);) { var m = a(p); n[m.enumerable] || (n[m.enumerable] = []), u = r(l), n[m.enumerable][d - 1] || (n[m.enumerable][d - 1] = {}), n[m.enumerable][d - 1][m.field] = u, d++, l = o(p, d) } } return n } function p() { return "undefined" != typeof bpmpi_config ? bpmpi_config() : { Debug: !0, Environment: "PRD" } } function c() { return D.Environment || "PRD" } function u() { var e = c(), r = { TST: "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js", SDB: "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js", PRD: "https://songbird.cardinalcommerce.com/edge/v1/songbird.js" }; return r[e] } function d() { return { orderNumber: r("bpmpi_ordernumber"), currency: r("bpmpi_currency"), amount: r("bpmpi_totalamount") } } function l(e) { var r = c(), n = { TST: "https://localhost:44351", SDB: "https://mpisandbox.braspag.com.br", PRD: "https://mpi.braspag.com.br" }; return n[r] + e } function m(e, r) { var n = document.getElementsByTagName("head")[0], i = document.createElement("script"); i.type = "text/javascript", i.src = e, i.onreadystatechange = r, i.onload = r, n.appendChild(i) } function _() { return "undefined" !== D.Debug ? D.Debug : !1 } function b() { _() && console.log.apply(null, arguments) } function h() { return _() ? "verbose" : "off" } function g(e, r) { T = r, b("[MPI]", "Initializing..."), b("[MPI]", "Token =", e), b("[MPI]", "ReferenceId =", T), Cardinal.configure({ timeout: "8000", maxRequestRetries: "10", logging: { level: h() } }), Cardinal.setup("init", { jwt: e }), Cardinal.on("payments.setupComplete", function (e) { b("[MPI]", "Setup complete."), b("[MPI]", "SetupCompleteData =", e), M("onReady") }), Cardinal.on("payments.validated", function (e) { switch (b("[MPI]", "Payment validated."), b("[MPI]", "ActionCode =", e.ActionCode), b("[MPI]", "Data =", e), e.ActionCode) { case "SUCCESS": case "NOACTION": case "FAILURE": A(e.Payment.ProcessorTransactionId); break; case "ERROR": k.Number = e.ErrorNumber, k.Description = e.ErrorDescription, e.Payment && e.Payment.ProcessorTransactionId ? A(e.Payment.ProcessorTransactionId) : M("onError", { Xid: null, Eci: null, ReturnCode: k.HasError() ? k.Number : "MPI901", ReturnMessage: k.HasError() ? k.Description : "Unexpected error", ReferenceId: null }); break; default: k.Number = e.ErrorNumber, k.Description = e.ErrorDescription, "Success" === e.ErrorDescription && e.Payment && e.Payment.ProcessorTransactionId ? A(e.Payment.ProcessorTransactionId) : M("onError", { Xid: null, Eci: null, ReturnCode: k.HasError() ? k.Number : "MPI902", ReturnMessage: k.HasError() ? k.Description : "Unexpected authentication response", ReferenceId: null }) } }) } function f(e, n, i) { var t = JSON.stringify(n), o = new XMLHttpRequest; o.onreadystatechange = function () { if (4 === this.readyState) if (200 === this.status) { var e = JSON.parse(o.responseText); i(e, this) } else M("onError", { Xid: null, Eci: null, ReturnCode: "MPI900", ReturnMessage: "An error has occurred (" + this.status + ")", ReferenceId: null }) }, o.open("POST", l(e)), o.setRequestHeader("Content-Type", "application/json"), o.setRequestHeader("Authorization", "Bearer " + r("bpmpi_accesstoken")), o.send(t) } function C() { var e = n("bpmpi_auth", "true"); return b("[MPI]", "Authentication Enabled =", e), "false" === e ? (M("onDisabled"), !1) : !0 } function E() { if (b("[MPI]", "Debug =", _()), b("[MPI]", "Enviroment =", c()), C()) { if (O) return void b("[MPI]", "Resources already loaded..."); b("[MPI]", "Loading resources..."), O = !0, m(u(), function () { b("[MPI]", "Cardinal script loaded."), f("/v2/3ds/init", d(), function (e) { g(e.Token, e.ReferenceId) }) }) } } function I() { if (C()) { if (!O) return void b("[MPI]", "Resources not loaded..."); b("[MPI]", "Enrolling..."), Cardinal.trigger("accountNumber.update", r("bpmpi_cardnumber")), f("/v2/3ds/enroll", s(), function (e) { b("[MPI]", "Enrollment result =", e), e.Version && (X = e.Version[0]); var r = e.Authentication; switch (e.Status) { case "ENROLLED": R(e); break; case "VALIDATION_NEEDED": A(e.AuthenticationTransactionId); break; case "AUTHENTICATION_CHECK_NEEDED": v(r); break; case "NOT_ENROLLED": M("onUnenrolled", { Xid: r.Xid, Eci: r.Eci, Version: X, ReferenceId: r.DirectoryServerTransactionId }); break; case "FAILED": M("onFailure", { Xid: r.Xid, Eci: r.Eci || r.EciRaw, Version: X, ReferenceId: r.DirectoryServerTransactionId }); break; case "UNSUPPORTED_BRAND": M("onUnsupportedBrand", { Xid: null, Eci: null, ReturnCode: e.ReturnCode, ReturnMessage: e.ReturnMessage, ReferenceId: null }); break; default: M("onError", { Xid: null, Eci: null, ReturnCode: e.ReturnCode, ReturnMessage: e.ReturnMessage, ReferenceId: null }) } }) } } function y(e, r) { return e[r] || null } function P(e) { b("[MPI] Building order object..."); var r = s(), n = { OrderDetails: { TransactionId: e, OrderNumber: r.ordernumber, CurrencyCode: y(r, "currency"), OrderChannel: r.transactionmode || "S" }, Consumer: { Account: { AccountNumber: r.cardnumber, ExpirationMonth: r.cardexpirationmonth, ExpirationYear: r.cardexpirationyear }, Email1: y(r, "shiptoemail"), Email2: y(r, "billtoemail"), ShippingAddress: { FullName: null, Address1: null, Address2: null, City: null, State: null, PostalCode: null, CountryCode: null, Phone1: null }, BillingAddress: { FullName: y(r, "billtocontactname"), Address1: y(r, "billtostreet1"), Address2: y(r, "billtostreet2"), City: y(r, "billtocity"), State: null === y(r, "billtostate") ? null : y(r, "billtostate").toUpperCase(), PostalCode: y(r, "billtozipcode"), CountryCode: y(r, "billtocountry"), Phone1: y(r, "billtophonenumber") } }, Cart: [] }; if ("true" === r.shiptosameasbillto) { var i = n.Consumer.BillingAddress; n.Consumer.ShippingAddress.FullName = i.FullName, n.Consumer.ShippingAddress.Address1 = i.Address1, n.Consumer.ShippingAddress.Address2 = i.Address2, n.Consumer.ShippingAddress.City = i.City, n.Consumer.ShippingAddress.State = i.State, n.Consumer.ShippingAddress.PostalCode = i.PostalCode, n.Consumer.ShippingAddress.Phone1 = i.Phone1, n.Consumer.ShippingAddress.CountryCode = i.CountryCode } else n.Consumer.ShippingAddress.FullName = y(r, "shiptoaddressee"), n.Consumer.ShippingAddress.Address1 = y(r, "shiptostreet1"), n.Consumer.ShippingAddress.Address2 = y(r, "shiptostreet2"), n.Consumer.ShippingAddress.City = y(r, "shiptocity"), n.Consumer.ShippingAddress.State = null === y(r, "shiptostate") ? null : y(r, "shiptostate").toUpperCase(), n.Consumer.ShippingAddress.PostalCode = y(r, "shiptozipcode"), n.Consumer.ShippingAddress.Phone1 = y(r, "shiptophonenumber"), n.Consumer.ShippingAddress.CountryCode = y(r, "shiptocountry"); if (r.cart) for (var t in r.cart) n.Cart.push({ Name: y(r.cart[t], "name"), Description: y(r.cart[t], "description"), SKU: y(r.cart[t], "sku"), Quantity: y(r.cart[t], "quantity"), Price: y(r.cart[t], "unitprice") }); return b("[MPI] Order object =", n), n } function R(e) { var n = r("bpmpi_auth_suppresschallenge"); if (b("[MPI] Suppression enabled = " + n), "true" === n) return b("[MPI]", "Challenge supressed..."), void M("onChallengeSuppression", { Xid: null, Eci: null, ReturnCode: "MPI601", ReturnMessage: "Challenge suppressed", ReferenceId: null }); b("[MPI]", "Showing challenge..."); var i = { AcsUrl: e.AcsUrl, Payload: e.Pareq, TransactionId: e.AuthenticationTransactionId }, t = P(e.AuthenticationTransactionId); b("[MPI] Continue object =", i), Cardinal.continue("cca", i, t) } function v(e) { switch (b("[MPI]", "Authentication result =", e), e.Status) { case "AUTHENTICATED": M("onSuccess", { Cavv: e.Cavv, Xid: e.Xid, Eci: e.Eci, Version: e.Version[0], ReferenceId: e.DirectoryServerTransactionId }); break; case "UNAVAILABLE": M("onUnenrolled", { Xid: e.Xid, Eci: e.Eci, Version: e.Version[0], ReferenceId: e.DirectoryServerTransactionId }); break; case "FAILED": M("onFailure", { Xid: e.Xid, Eci: e.Eci || e.EciRaw, Version: e.Version[0], ReferenceId: e.DirectoryServerTransactionId }); break; case "ERROR_OCCURRED": M("onError", { Xid: e.Xid, Eci: e.Eci || e.EciRaw, ReturnCode: e.ReturnCode, ReturnMessage: e.ReturnMessage, ReferenceId: e.DirectoryServerTransactionId }); break; default: M("onError", { Xid: e.Xid, Eci: e.Eci || e.EciRaw, ReturnCode: k.HasError() ? k.Number : e.ReturnCode, ReturnMessage: k.HasError() ? k.Description : e.ReturnMessage, ReferenceId: e.DirectoryServerTransactionId }) } } function A(e) { var r = s(); r.transactionId = e, b("[MPI]", "Validating..."), f("/v2/3ds/validate", r, function (e) { v(e) }) } function S(e) { return "function" == typeof D[e] } function M(e, r) { b("[MPI]", "Notifying..."), b("[MPI]", "Event type =", e), b("[MPI]", "Event data =", r || "None"), S(e) && D[e](r) } var D = p(), N = ["bpmpi_transaction_mode", "bpmpi_merchant_url", "bpmpi_merchant_newcustomer", "bpmpi_ordernumber", "bpmpi_currency", "bpmpi_totalamount", "bpmpi_paymentmethod", "bpmpi_installments", "bpmpi_cardnumber", "bpmpi_cardexpirationmonth", "bpmpi_cardexpirationyear", "bpmpi_cardalias", "bpmpi_default_card", "bpmpi_cardaddeddate", "bpmpi_giftcard_amount", "bpmpi_giftcard_currency", "bpmpi_billto_customerid", "bpmpi_billto_contactname", "bpmpi_billto_email", "bpmpi_billto_street1", "bpmpi_billto_street2", "bpmpi_billto_city", "bpmpi_billto_state", "bpmpi_billto_zipcode", "bpmpi_billto_phonenumber", "bpmpi_billto_country", "bpmpi_shipto_sameasbillto", "bpmpi_shipto_addressee", "bpmpi_shipto_email", "bpmpi_shipto_street1", "bpmpi_shipto_street2", "bpmpi_shipto_city", "bpmpi_shipto_state", "bpmpi_shipto_zipcode", "bpmpi_shipto_shippingmethod", "bpmpi_shipto_phonenumber", "bpmpi_shipto_firstusagedate", "bpmpi_shipto_country", "bpmpi_device_ipaddress", "bpmpi_device_#_fingerprint", "bpmpi_device_#_provider", "bpmpi_cart_#_name", "bpmpi_cart_#_description", "bpmpi_cart_#_sku", "bpmpi_cart_#_quantity", "bpmpi_cart_#_unitprice", "bpmpi_order_recurrence", "bpmpi_order_productcode", "bpmpi_order_countlast24hours", "bpmpi_order_countlast6months", "bpmpi_order_countlast1year", "bpmpi_order_cardattemptslast24hours", "bpmpi_order_marketingoptin", "bpmpi_order_marketingsource", "bpmpi_useraccount_guest", "bpmpi_useraccount_createddate", "bpmpi_useraccount_changeddate", "bpmpi_useraccount_passwordchangeddate", "bpmpi_useraccount_authenticationmethod", "bpmpi_useraccount_authenticationprotocol", "bpmpi_useraccount_authenticationtimestamp", "bpmpi_airline_travelleg_#_carrier", "bpmpi_airline_travelleg_#_departuredate", "bpmpi_airline_travelleg_#_origin", "bpmpi_airline_travelleg_#_destination", "bpmpi_airline_passenger_#_name", "bpmpi_airline_passenger_#_ticketprice", "bpmpi_airline_numberofpassengers", "bpmpi_airline_billto_passportcountry", "bpmpi_airline_billto_passportnumber", "bpmpi_mdd1", "bpmpi_mdd2", "bpmpi_mdd3", "bpmpi_mdd4", "bpmpi_mdd5", "bpmpi_auth_notifyonly", "bpmpi_auth_suppresschallenge", "bpmpi_recurring_enddate", "bpmpi_recurring_frequency", "bpmpi_recurring_originalpurchasedate"], T = null, X = null, k = { Number: null, Description: null, HasError: function () { return null !== this.Number } }, O = !1; return { Mpi: { load: function () { E() }, authenticate: function () { I() } } } }(); bpmpi_load(); \ No newline at end of file diff --git a/resources/js/debitCard/lkn-dc-script-prd.js b/resources/js/debitCard/lkn-dc-script-prd.js new file mode 100644 index 0000000..23d46e2 --- /dev/null +++ b/resources/js/debitCard/lkn-dc-script-prd.js @@ -0,0 +1,78 @@ +/* eslint-disable no-undef */ +// Implements script internationalization + +function bpmpi_config () { + return { + onReady: function () { + }, + onSuccess: function (e) { + // Card is eligible for authentication, and the bearer successfully authenticated + const cavv = e.Cavv + const xid = e.Xid + const eci = e.Eci + const version = e.Version + const referenceId = e.ReferenceId + + const Form3dsButton = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0].closest('form') + + Form3dsButton.setAttribute('data-payment-cavv', cavv) + Form3dsButton.setAttribute('data-payment-eci', eci) + Form3dsButton.setAttribute('data-payment-ref_id', referenceId) + Form3dsButton.setAttribute('data-payment-version', version) + Form3dsButton.setAttribute('data-payment-xid', xid) + + if (Form3dsButton) { + const Button3ds = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0] + const event = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }) + + Button3ds.dispatchEvent(event) + } else { + console.error('Form3dsButton não encontrado.') + } + }, + onFailure: function (e) { + // Card is not eligible for authentication, but the bearer failed payment + alert(__('Authentication failed check the card information and try again', 'lkn-wc-gateway-cielo')) + }, + onUnenrolled: function (e) { + // Card is not eligible for authentication (unauthenticable) + alert(__('Card Ineligible for Authentication', 'lkn-wc-gateway-cielo')) + }, + onDisabled: function () { + // Store don't require bearer authentication (class "bpmpi_auth" false -> disabled authentication). + alert(__('Authentication disabled by the store', 'lkn-wc-gateway-cielo')) + }, + onError: function (e) { + // Error on proccess in authentication + alert(__('Error in the 3DS 2.0 authentication process check that your credentials are filled in correctly', 'lkn-wc-gateway-cielo')) + }, + onUnsupportedBrand: function (e) { + // Provider not supported for authentication + alert(__('Provider not supported by Cielo 3DS authentication', 'lkn-wc-gateway-cielo')) + }, + + Environment: 'PRD', // SDB or PRD + Debug: false // true or false + } +} + +function lknProccessButton () { + try { + const cardNumber = document.getElementById('lkn_dcno').value.replace(/\D/g, '') + let expDate = document.getElementById('lkn_dc_expdate').value + + expDate = expDate.split('/') + + document.getElementById('lkn_bpmpi_cardnumber').value = cardNumber + document.getElementById('lkn_bpmpi_expmonth').value = expDate[0].replace(/\D/g, '') + document.getElementById('lkn_bpmpi_expyear').value = expDate[1].replace(/\D/g, '') + + bpmpi_authenticate() + } catch (error) { + alert(__('Authentication failed check the card information and try again', 'lkn-wc-gateway-cielo')) + } +} diff --git a/resources/js/debitCard/lkn-dc-script-sdb.js b/resources/js/debitCard/lkn-dc-script-sdb.js new file mode 100644 index 0000000..01f69f1 --- /dev/null +++ b/resources/js/debitCard/lkn-dc-script-sdb.js @@ -0,0 +1,78 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-undef */ +// Implements script internationalization + +function bpmpi_config () { + return { + onReady: function () { + }, + onSuccess: function (e) { + // Card is eligible for authentication, and the bearer successfully authenticated + const cavv = e.Cavv + const xid = e.Xid + const eci = e.Eci + const version = e.Version + const referenceId = e.ReferenceId + + const Form3dsButton = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0].closest('form') + + Form3dsButton.setAttribute('data-payment-cavv', cavv) + Form3dsButton.setAttribute('data-payment-eci', eci) + Form3dsButton.setAttribute('data-payment-ref_id', referenceId) + Form3dsButton.setAttribute('data-payment-version', version) + Form3dsButton.setAttribute('data-payment-xid', xid) + + if (Form3dsButton) { + const Button3ds = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0] + const event = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }) + Button3ds.dispatchEvent(event) + } else { + console.error('Form3dsButton não encontrado.') + } + }, + onFailure: function (e) { + // Card is not eligible for authentication, but the bearer failed payment + alert(__('Authentication failed check the card information and try again', 'lkn-wc-gateway-cielo')) + }, + onUnenrolled: function (e) { + // Card is not eligible for authentication (unauthenticable) + alert(__('Card Ineligible for Authentication', 'lkn-wc-gateway-cielo')) + }, + onDisabled: function () { + // Store don't require bearer authentication (class "bpmpi_auth" false -> disabled authentication). + alert(__('Authentication disabled by the store', 'lkn-wc-gateway-cielo')) + }, + onError: function (e) { + // Error on proccess in authentication + alert(__('Error in the 3DS 2.0 authentication process check that your credentials are filled in correctly', 'lkn-wc-gateway-cielo')) + }, + onUnsupportedBrand: function (e) { + // Provider not supported for authentication + alert(__('Provider not supported by Cielo 3DS authentication', 'lkn-wc-gateway-cielo')) + }, + + Environment: 'SDB', // SDB or PRD + Debug: true // true or false + } +} + +function lknProccessButton () { + try { + const cardNumber = document.getElementById('lkn_dcno').value.replace(/\D/g, '') + let expDate = document.getElementById('lkn_dc_expdate').value + + expDate = expDate.split('/') + + document.getElementById('lkn_bpmpi_cardnumber').value = cardNumber + document.getElementById('lkn_bpmpi_expmonth').value = expDate[0].replace(/\D/g, '') + document.getElementById('lkn_bpmpi_expyear').value = expDate[1].replace(/\D/g, '') + + bpmpi_authenticate() + } catch (error) { + alert(__('Authentication failed check the card information and try again', 'lkn-wc-gateway-cielo')) + } +} diff --git a/resources/js/debitCard/lknCieloDebit.js b/resources/js/debitCard/lknCieloDebit.js new file mode 100644 index 0000000..0afcc24 --- /dev/null +++ b/resources/js/debitCard/lknCieloDebit.js @@ -0,0 +1,305 @@ +const settingsDebitCard = window.wc.wcSettings.getSetting('lkn_cielo_debit_data', {}); +const labelDebitCard = window.wp.htmlEntities.decodeEntities(settingsDebitCard.title); +const accessToken = window.wp.htmlEntities.decodeEntities(settingsDebitCard.accessToken); +const url = window.wp.htmlEntities.decodeEntities(settingsDebitCard.url); +const totalCart = window.wp.htmlEntities.decodeEntities(settingsDebitCard.totalCart); +const orderNumber = window.wp.htmlEntities.decodeEntities(settingsDebitCard.orderNumber); +const dirScript3DS = window.wp.htmlEntities.decodeEntities(settingsDebitCard.dirScript3DS); +const dirScriptConfig3DS = window.wp.htmlEntities.decodeEntities(settingsDebitCard.dirScriptConfig3DS); +const translationsDebit = settingsDebitCard.translations; +const nonceCieloDebit = settingsDebitCard.nonceCieloDebit; +const Content_cieloDebit = props => { + const wcComponents = window.wc.blocksComponents; + const { + eventRegistration, + emitResponse + } = props; + const { + onPaymentSetup + } = eventRegistration; + const [debitObject, setdebitObject] = window.wp.element.useState({ + lkn_dcno: '', + lkn_dc_expdate: '', + lkn_dc_cvc: '' + }); + const formatDebitCardNumber = value => { + if (value?.length > 19) return debitObject.lkn_dcno; + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, ''); + // Adiciona espaços a cada quatro dígitos + const formattedValue = cleanedValue?.replace(/(.{4})/g, '$1 ')?.trim(); + return formattedValue; + }; + const updatedebitObject = (key, value) => { + switch (key) { + case 'lkn_dc_expdate': + if (value.length > 7) return; + + // Verifica se o valor é uma data válida (MM/YY) + const isValidDate = /^\d{2}\/\d{2}$/.test(value); + if (!isValidDate) { + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, ''); + let formattedValue = cleanedValue?.replace(/^(.{2})/, '$1 / ')?.trim(); + + // Se o tamanho da string for 5, remove o espaço e a barra adicionados anteriormente + if (formattedValue.length === 4) { + formattedValue = formattedValue.replace(/\s\//, ''); + } + + // Atualiza o estado + setdebitObject({ + ...debitObject, + [key]: formattedValue + }); + } + return; + case 'lkn_dc_cvc': + if (value.length > 4) return; + break; + default: + break; + } + setdebitObject({ + ...debitObject, + [key]: value + }); + }; + window.wp.element.useEffect(() => { + const elemento = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0]; + elemento.style.display = 'none'; + return () => { + elemento.style.display = ''; + }; + }); + window.wp.element.useEffect(() => { + const scriptUrl = dirScript3DS; + const existingScript = document.querySelector(`script[src="${scriptUrl}"]`); + if (!existingScript) { + const script = document.createElement('script'); + script.src = scriptUrl; + script.async = true; + document.body.appendChild(script); + } + }, []); + window.wp.element.useEffect(() => { + const scriptUrl = dirScriptConfig3DS; + const existingScript = document.querySelector(`script[src="${scriptUrl}"]`); + if (!existingScript) { + const script = document.createElement('script'); + script.src = scriptUrl; + script.async = true; + document.body.appendChild(script); + } + }, []); + const handleButtonClick = () => { + // Verifica se todos os campos do debitObject estão preenchidos + const allFieldsFilled = Object.values(debitObject).every(field => field.trim() !== ''); + + // Seleciona os elementos dos campos de entrada + const cardNumberInput = document.getElementById('lkn_dcno'); + const expDateInput = document.getElementById('lkn_dc_expdate'); + const cvvInput = document.getElementById('lkn_dc_cvc'); + + // Remove classes de erro e mensagens de validação existentes + cardNumberInput?.classList.remove('has-error'); + expDateInput?.classList.remove('has-error'); + cvvInput?.classList.remove('has-error'); + if (allFieldsFilled) { + lknProccessButton(); + } else { + // Adiciona classes de erro aos campos vazios + if (debitObject.lkn_dcno.trim() === '') { + const parentDiv = cardNumberInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + if (debitObject.lkn_dc_expdate.trim() === '') { + const parentDiv = expDateInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + if (debitObject.lkn_dc_cvc.trim() === '') { + const parentDiv = cvvInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + } + }; + window.wp.element.useEffect(() => { + const unsubscribe = onPaymentSetup(async () => { + const Button3dsEnviar = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0].closest('form'); + const paymentCavv = Button3dsEnviar?.getAttribute('data-payment-cavv'); + const paymentEci = Button3dsEnviar?.getAttribute('data-payment-eci'); + const paymentReferenceId = Button3dsEnviar?.getAttribute('data-payment-ref_id'); + const paymentVersion = Button3dsEnviar?.getAttribute('data-payment-version'); + const paymentXid = Button3dsEnviar?.getAttribute('data-payment-xid'); + return { + type: emitResponse.responseTypes.SUCCESS, + meta: { + paymentMethodData: { + lkn_dcno: debitObject.lkn_dcno, + lkn_dc_expdate: debitObject.lkn_dc_expdate, + lkn_dc_cvc: debitObject.lkn_dc_cvc, + nonce_lkn_cielo_debit: nonceCieloDebit, + lkn_cielo_3ds_cavv: paymentCavv, + lkn_cielo_3ds_eci: paymentEci, + lkn_cielo_3ds_ref_id: paymentReferenceId, + lkn_cielo_3ds_version: paymentVersion, + lkn_cielo_3ds_xid: paymentXid + } + } + }; + }); + + // Cancela a inscrição quando este componente é desmontado. + return () => { + unsubscribe(); + }; + }, [debitObject, emitResponse.responseTypes.ERROR, emitResponse.responseTypes.SUCCESS, onPaymentSetup]); + return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("h4", null, "Pagamento processado pela Cielo API 3.0")), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_dcno", + label: translationsDebit.cardNumber, + value: debitObject.lkn_dcno, + onChange: value => { + updatedebitObject('lkn_dcno', formatDebitCardNumber(value)); + }, + required: true + }), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_dc_expdate", + label: translationsDebit.cardExpiryDate, + value: debitObject.lkn_dc_expdate, + onChange: value => { + updatedebitObject('lkn_dc_expdate', value); + }, + required: true + }), /*#__PURE__*/React.createElement(wcComponents.TextInput, { + id: "lkn_dc_cvc", + label: translationsDebit.securityCode, + value: debitObject.lkn_dc_cvc, + onChange: value => { + updatedebitObject('lkn_dc_cvc', value); + }, + required: true + }), /*#__PURE__*/React.createElement("div", { + style: { + marginBottom: '30px' + } + }), /*#__PURE__*/React.createElement("div", { + style: { + display: 'flex', + justifyContent: 'center' + } + }, /*#__PURE__*/React.createElement(wcComponents.Button, { + id: "sendOrder", + onClick: handleButtonClick + }, /*#__PURE__*/React.createElement("span", null, "Finalizar pedido"))), /*#__PURE__*/React.createElement("div", { + style: { + marginBottom: '20px' + } + }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", { + type: "hidden", + name: "lkn_auth_enabled", + className: "bpmpi_auth", + value: "true" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + name: "lkn_auth_enabled_notifyonly", + className: "bpmpi_auth_notifyonly", + value: "true" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + name: "lkn_access_token", + className: "bpmpi_accesstoken", + value: accessToken + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + size: "50", + name: "lkn_order_number", + className: "bpmpi_ordernumber", + value: orderNumber + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + name: "lkn_currency", + className: "bpmpi_currency", + value: "BRL" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + size: "50", + className: "bpmpi_merchant_url", + value: url + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + size: "50", + id: "lkn_cielo_3ds_value", + name: "lkn_amount", + className: "bpmpi_totalamount", + value: totalCart + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + size: "2", + name: "lkn_installments", + className: "bpmpi_installments", + value: "1" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + name: "lkn_payment_method", + className: "bpmpi_paymentmethod", + value: "Debit" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_bpmpi_cardnumber", + className: "bpmpi_cardnumber" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_bpmpi_expmonth", + maxLength: "2", + name: "lkn_card_expiry_month", + className: "bpmpi_cardexpirationmonth" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_bpmpi_expyear", + maxLength: "4", + name: "lkn_card_expiry_year", + className: "bpmpi_cardexpirationyear" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + size: "50", + className: "bpmpi_order_productcode", + value: "PHY" + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_cavv", + name: "lkn_cielo_3ds_cavv", + value: true + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_eci", + name: "lkn_cielo_3ds_eci", + value: true + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_ref_id", + name: "lkn_cielo_3ds_ref_id", + value: true + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_version", + name: "lkn_cielo_3ds_version", + value: true + }), /*#__PURE__*/React.createElement("input", { + type: "hidden", + id: "lkn_xid", + name: "lkn_cielo_3ds_xid", + value: true + }))); +}; +const Block_Gateway_Debit_Card = { + name: 'lkn_cielo_debit', + label: labelDebitCard, + content: window.wp.element.createElement(Content_cieloDebit), + edit: window.wp.element.createElement(Content_cieloDebit), + canMakePayment: () => true, + ariaLabel: labelDebitCard, + supports: { + features: settingsDebitCard.supports + } +}; +window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway_Debit_Card); \ No newline at end of file diff --git a/resources/js/debitCard/lknCieloDebit.tsx b/resources/js/debitCard/lknCieloDebit.tsx new file mode 100644 index 0000000..04a5e8e --- /dev/null +++ b/resources/js/debitCard/lknCieloDebit.tsx @@ -0,0 +1,261 @@ +const settingsDebitCard = window.wc.wcSettings.getSetting('lkn_cielo_debit_data', {}) +const labelDebitCard = window.wp.htmlEntities.decodeEntities(settingsDebitCard.title) +const accessToken = window.wp.htmlEntities.decodeEntities(settingsDebitCard.accessToken) +const url = window.wp.htmlEntities.decodeEntities(settingsDebitCard.url) +const totalCart = window.wp.htmlEntities.decodeEntities(settingsDebitCard.totalCart) +const orderNumber = window.wp.htmlEntities.decodeEntities(settingsDebitCard.orderNumber) +const dirScript3DS = window.wp.htmlEntities.decodeEntities(settingsDebitCard.dirScript3DS) +const dirScriptConfig3DS = window.wp.htmlEntities.decodeEntities(settingsDebitCard.dirScriptConfig3DS) +const translationsDebit = settingsDebitCard.translations +const nonceCieloDebit = settingsDebitCard.nonceCieloDebit; + +const Content_cieloDebit = (props) => { + const wcComponents = window.wc.blocksComponents + const { eventRegistration, emitResponse } = props + const { onPaymentSetup } = eventRegistration + + const [debitObject, setdebitObject] = window.wp.element.useState({ + lkn_dcno: '', + lkn_dc_expdate: '', + lkn_dc_cvc: '', + }) + + const formatDebitCardNumber = value => { + if (value?.length > 19) return debitObject.lkn_dcno + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, '') + // Adiciona espaços a cada quatro dígitos + const formattedValue = cleanedValue?.replace(/(.{4})/g, '$1 ')?.trim() + return formattedValue + } + + const updatedebitObject = (key, value) => { + switch (key) { + case 'lkn_dc_expdate': + if (value.length > 7) return + + // Verifica se o valor é uma data válida (MM/YY) + const isValidDate = /^\d{2}\/\d{2}$/.test(value) + if (!isValidDate) { + // Remove caracteres não numéricos + const cleanedValue = value?.replace(/\D/g, '') + let formattedValue = cleanedValue?.replace(/^(.{2})/, '$1 / ')?.trim() + + // Se o tamanho da string for 5, remove o espaço e a barra adicionados anteriormente + if (formattedValue.length === 4) { + formattedValue = formattedValue.replace(/\s\//, '') + } + + // Atualiza o estado + setdebitObject({ + ...debitObject, + [key]: formattedValue + }) + } + return + case 'lkn_dc_cvc': + if (value.length > 4) return + break + default: + break + } + setdebitObject({ + ...debitObject, + [key]: value + }) + } + + window.wp.element.useEffect(() => { + const elemento = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0] + + elemento.style.display = 'none'; + + return () => { + elemento.style.display = ''; + }; + }) + + window.wp.element.useEffect(() => { + const scriptUrl = dirScript3DS; + const existingScript = document.querySelector(`script[src="${scriptUrl}"]`); + + if (!existingScript) { + const script = document.createElement('script'); + script.src = scriptUrl; + script.async = true; + document.body.appendChild(script); + } + }, []); + + window.wp.element.useEffect(() => { + const scriptUrl = dirScriptConfig3DS; + const existingScript = document.querySelector(`script[src="${scriptUrl}"]`); + if (!existingScript) { + const script = document.createElement('script'); + script.src = scriptUrl; + script.async = true; + document.body.appendChild(script); + } + }, []); + + + const handleButtonClick = () => { + // Verifica se todos os campos do debitObject estão preenchidos + const allFieldsFilled = Object.values(debitObject).every((field) => field.trim() !== ''); + + // Seleciona os elementos dos campos de entrada + const cardNumberInput = document.getElementById('lkn_dcno'); + const expDateInput = document.getElementById('lkn_dc_expdate'); + const cvvInput = document.getElementById('lkn_dc_cvc'); + + // Remove classes de erro e mensagens de validação existentes + cardNumberInput?.classList.remove('has-error'); + expDateInput?.classList.remove('has-error'); + cvvInput?.classList.remove('has-error'); + + if (allFieldsFilled) { + lknProccessButton(); + } else { + // Adiciona classes de erro aos campos vazios + if (debitObject.lkn_dcno.trim() === '') { + const parentDiv = cardNumberInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + + if (debitObject.lkn_dc_expdate.trim() === '') { + const parentDiv = expDateInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + + if (debitObject.lkn_dc_cvc.trim() === '') { + const parentDiv = cvvInput?.parentElement; + parentDiv?.classList.add('has-error'); + } + } + }; + + window.wp.element.useEffect(() => { + const unsubscribe = onPaymentSetup(async () => { + const Button3dsEnviar = document.querySelectorAll('.wc-block-components-checkout-place-order-button')[0].closest('form') + + const paymentCavv = Button3dsEnviar?.getAttribute('data-payment-cavv'); + const paymentEci = Button3dsEnviar?.getAttribute('data-payment-eci'); + const paymentReferenceId = Button3dsEnviar?.getAttribute('data-payment-ref_id'); + const paymentVersion = Button3dsEnviar?.getAttribute('data-payment-version'); + const paymentXid = Button3dsEnviar?.getAttribute('data-payment-xid'); + + return { + type: emitResponse.responseTypes.SUCCESS, + meta: { + paymentMethodData: { + lkn_dcno: debitObject.lkn_dcno, + lkn_dc_expdate: debitObject.lkn_dc_expdate, + lkn_dc_cvc: debitObject.lkn_dc_cvc, + nonce_lkn_cielo_debit: nonceCieloDebit, + lkn_cielo_3ds_cavv: paymentCavv, + lkn_cielo_3ds_eci: paymentEci, + lkn_cielo_3ds_ref_id: paymentReferenceId, + lkn_cielo_3ds_version: paymentVersion, + lkn_cielo_3ds_xid: paymentXid, + }, + }, + }; + } + ); + + // Cancela a inscrição quando este componente é desmontado. + return () => { + unsubscribe(); + }; + }, [debitObject, + emitResponse.responseTypes.ERROR, + emitResponse.responseTypes.SUCCESS, + onPaymentSetup + ]); + + return ( + <> +
+

Pagamento processado pela Cielo API 3.0

+
+ + { + updatedebitObject('lkn_dcno', formatDebitCardNumber(value)) + }} + required + /> + + { + updatedebitObject('lkn_dc_expdate', value) + }} + required + /> + + { + updatedebitObject('lkn_dc_cvc', value) + }} + required + /> + +
+ +
+ + Finalizar pedido + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + +
+ + ) +} + +const Block_Gateway_Debit_Card = { + name: 'lkn_cielo_debit', + label: labelDebitCard, + content: window.wp.element.createElement(Content_cieloDebit), + edit: window.wp.element.createElement(Content_cieloDebit), + canMakePayment: () => true, + ariaLabel: labelDebitCard, + supports: { + features: settingsDebitCard.supports + } +}; + +window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway_Debit_Card) \ No newline at end of file diff --git a/resources/js/frontend/lkn-dc-script-sdb.js b/resources/js/frontend/lkn-dc-script-sdb.js index b6aa625..dc5a73c 100755 --- a/resources/js/frontend/lkn-dc-script-sdb.js +++ b/resources/js/frontend/lkn-dc-script-sdb.js @@ -69,7 +69,6 @@ const { __ } = wp.i18n; function bpmpi_config () { return { onReady: function () { - }, onSuccess: function (e) { // Card is eligible for authentication, and the bearer successfully authenticated