diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a6cf7ccb3..fc25de35a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,13 @@ name: Tests -on: [ push, pull_request, workflow_dispatch ] +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: jobs: ci-legacy: @@ -14,7 +21,7 @@ jobs: name: Shopware ${{ matrix.shopware-versions }} on PHP ${{ matrix.php-versions }} services: mysql: - image: mariadb:10.5.9 + image: mysql:5.7.38 env: MYSQL_ROOT_PASSWORD: root ports: @@ -60,7 +67,9 @@ jobs: run: | cd /tmp/shopware composer dumpautoload -d /tmp/shopware/custom/plugins/PayonePayment - /tmp/shopware/vendor/bin/phpunit --configuration /tmp/shopware/custom/plugins/PayonePayment/phpunit.xml.dist + /tmp/shopware/vendor/bin/phpunit \ + --testdox \ + --configuration /tmp/shopware/custom/plugins/PayonePayment/phpunit-legacy.xml.dist ci-current: runs-on: ubuntu-latest strategy: @@ -72,7 +81,7 @@ jobs: name: Shopware ${{ matrix.shopware-versions }} on PHP ${{ matrix.php-versions }} services: mysql: - image: mariadb:10.5.9 + image: mysql:5.7.38 env: MYSQL_ROOT_PASSWORD: root ports: @@ -117,4 +126,8 @@ jobs: php bin/console plugin:install --activate PayonePayment - name: PHPUnit run: | - /tmp/shopware/custom/plugins/PayonePayment/vendor/bin/phpunit --configuration /tmp/shopware/custom/plugins/PayonePayment/phpunit.xml.dist + PROJECT_ROOT=/tmp/shopware \ + TEST_DATABASE_URL="mysql://root:root@127.0.0.1:3306/shopware" \ + /tmp/shopware/custom/plugins/PayonePayment/vendor/bin/phpunit \ + --testdox \ + --configuration /tmp/shopware/custom/plugins/PayonePayment/phpunit.xml.dist diff --git a/.php_cs.dist b/.php_cs.dist index c7f519a35..e84562be9 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -4,7 +4,8 @@ require 'vendor/autoload.php'; $finder = PhpCsFixer\Finder::create() ->in(__DIR__ . '/src') - ->in(__DIR__ . '/tests'); + ->in(__DIR__ . '/tests') + ->in(__DIR__ . '/tests_legacy'); return K10r\Codestyle\PHP72::create($finder, [ // Allow multiline throw expressions diff --git a/composer.json b/composer.json index 5773ac1b0..7f1c7ab4c 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "k10r/codestyle": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "9.5.2" + "phpunit/phpunit": "^9.5" }, "autoload": { "psr-4": { @@ -41,7 +41,8 @@ }, "autoload-dev": { "psr-4": { - "PayonePayment\\Test\\": "tests/" + "PayonePayment\\": "tests/", + "PayonePayment\\Test\\": "tests_legacy/" } }, "config": { diff --git a/composer.lock b/composer.lock index 459d0a77a..918a9f178 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4d88d8b504b84bdfc62af6065ef24093", + "content-hash": "246ee5c5e21ba995735571efc5686938", "packages": [ { "name": "sinergi/browser-detector", @@ -108,29 +108,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -157,7 +158,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -173,7 +174,7 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "k10r/codestyle", @@ -223,37 +224,38 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -269,7 +271,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -277,20 +279,20 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.0", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -331,9 +333,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2021-09-20T12:20:58+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "phar-io/manifest", @@ -397,16 +399,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -442,9 +444,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -558,16 +560,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { @@ -602,22 +604,22 @@ "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.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -669,9 +671,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpstan/phpstan", @@ -793,23 +795,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.7", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.12.0", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -858,7 +860,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" }, "funding": [ { @@ -866,20 +868,20 @@ "type": "github" } ], - "time": "2021-09-17T05:39:03+00:00" + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -918,7 +920,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -926,7 +928,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -1111,16 +1113,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.2", + "version": "9.5.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" + "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", - "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e32b76be457de00e83213528f6bb37e2a38fcb1", + "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1", "shasum": "" }, "require": { @@ -1132,11 +1134,11 @@ "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.1", + "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -1150,11 +1152,10 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*", "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { @@ -1171,11 +1172,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1198,11 +1199,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -1210,7 +1211,7 @@ "type": "github" } ], - "time": "2021-02-02T14:45:58+00:00" + "time": "2022-06-19T12:14:25+00:00" }, { "name": "sebastian/cli-parser", @@ -1578,16 +1579,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { @@ -1629,7 +1630,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" }, "funding": [ { @@ -1637,20 +1638,20 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -1699,14 +1700,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -1714,20 +1715,20 @@ "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -1770,7 +1771,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -1778,7 +1779,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", @@ -2069,28 +2070,28 @@ }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2113,7 +2114,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -2121,7 +2122,7 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -2176,85 +2177,6 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.23.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "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.23.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": "2021-02-19T12:13:01+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.1", @@ -2307,21 +2229,21 @@ }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -2359,9 +2281,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], @@ -2374,5 +2296,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/phpunit-legacy.xml.dist b/phpunit-legacy.xml.dist new file mode 100644 index 000000000..d1e8a4b25 --- /dev/null +++ b/phpunit-legacy.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + tests_legacy + + + + + + ./src + + + \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index bb68cd47b..066d4737d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,19 +1,17 @@ + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" + bootstrap="./tests/TestBootstrap.php" + colors="true"> - - - - + @@ -22,9 +20,9 @@ - - - ./ - - + + + src + + diff --git a/src/Components/ConfigReader/ConfigReader.php b/src/Components/ConfigReader/ConfigReader.php index f5596f463..176d9fe72 100644 --- a/src/Components/ConfigReader/ConfigReader.php +++ b/src/Components/ConfigReader/ConfigReader.php @@ -4,6 +4,7 @@ namespace PayonePayment\Components\ConfigReader; +use PayonePayment\Configuration\ConfigurationPrefixes; use PayonePayment\Struct\Configuration; use Shopware\Core\System\SystemConfig\SystemConfigService; @@ -19,6 +20,11 @@ public function __construct(SystemConfigService $systemConfigService) $this->systemConfigService = $systemConfigService; } + public static function getConfigKeyByPaymentHandler(string $paymentHandler, string $configuration): string + { + return self::SYSTEM_CONFIG_DOMAIN . ConfigurationPrefixes::CONFIGURATION_PREFIXES[$paymentHandler] . $configuration; + } + public function read(?string $salesChannelId = null, bool $fallback = true): Configuration { $values = $this->systemConfigService->getDomain( diff --git a/src/Components/Helper/OrderFetcher.php b/src/Components/Helper/OrderFetcher.php index c00737c0a..c0ad08cbb 100644 --- a/src/Components/Helper/OrderFetcher.php +++ b/src/Components/Helper/OrderFetcher.php @@ -4,6 +4,8 @@ namespace PayonePayment\Components\Helper; +use RuntimeException; +use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; @@ -34,12 +36,54 @@ public function getOrderById(string $orderId, Context $context): ?OrderEntity return $this->orderRepository->search($criteria, $context)->first(); } + public function getOrderBillingAddress(OrderEntity $order): OrderAddressEntity + { + $orderAddresses = $order->getAddresses(); + + if (null === $orderAddresses) { + throw new RuntimeException('missing order addresses'); + } + + /** @var OrderAddressEntity $billingAddress */ + $billingAddress = $orderAddresses->get($order->getBillingAddressId()); + + if (null === $billingAddress) { + throw new RuntimeException('missing order billing address'); + } + + return $billingAddress; + } + + public function getOrderShippingAddress(OrderEntity $order): OrderAddressEntity + { + $orderAddresses = $order->getAddresses(); + + if (null === $orderAddresses) { + throw new RuntimeException('missing order addresses'); + } + + $deliveries = $order->getDeliveries(); + + if ($deliveries && $deliveries->first()) { + $shippingAddressId = $deliveries->first()->getShippingOrderAddressId(); + + /** @var OrderAddressEntity $shippingAddress */ + $shippingAddress = $orderAddresses->get($shippingAddressId); + + if ($shippingAddress) { + return $shippingAddress; + } + } + + return $this->getOrderBillingAddress($order); + } + private function getOrderCriteria(): Criteria { $criteria = new Criteria(); $criteria->addAssociation('transactions'); $criteria->addAssociation('transactions.stateMachineState'); - $criteria->addAssociation('orderCustomer'); + $criteria->addAssociation('orderCustomer.customer'); $criteria->addAssociation('addresses'); $criteria->addAssociation('addresses.salutation'); $criteria->addAssociation('addresses.country'); diff --git a/src/Components/Helper/OrderFetcherInterface.php b/src/Components/Helper/OrderFetcherInterface.php index 3ba419e99..ffb27450d 100644 --- a/src/Components/Helper/OrderFetcherInterface.php +++ b/src/Components/Helper/OrderFetcherInterface.php @@ -4,10 +4,15 @@ namespace PayonePayment\Components\Helper; +use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; interface OrderFetcherInterface { public function getOrderById(string $orderId, Context $context): ?OrderEntity; + + public function getOrderBillingAddress(OrderEntity $order): OrderAddressEntity; + + public function getOrderShippingAddress(OrderEntity $order): OrderAddressEntity; } diff --git a/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintService.php b/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintService.php new file mode 100644 index 000000000..c0ec1a3cb --- /dev/null +++ b/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintService.php @@ -0,0 +1,67 @@ +session = $session; + } + + public function isDeviceIdentTokenAlreadyGenerated(): bool + { + return $this->session->get(self::SESSION_VAR_NAME) !== null; + } + + public function getDeviceIdentToken(): string + { + $sessionValue = $this->session->get(self::SESSION_VAR_NAME); + + if ($sessionValue) { + $token = $sessionValue; + } else { + $sessionId = $this->session->get('sessionId'); + $token = md5($sessionId . '_' . microtime()); + $this->session->set(self::SESSION_VAR_NAME, $token); + } + + return $token; + } + + public function deleteDeviceIdentToken(): void + { + $this->session->remove(self::SESSION_VAR_NAME); + } + + public function getDeviceIdentSnippet(string $snippetId, string $deviceIdentToken): string + { + $location = 'Checkout'; + + $snippet = sprintf( + '', + json_encode([ + 'v' => $snippetId, + 't' => $deviceIdentToken, + 'l' => $location, + ]) + ); + + $snippet .= sprintf( + ' + ', + $snippetId, + $deviceIdentToken, + $location + ); + + return $snippet; + } +} diff --git a/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintServiceInterface.php b/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintServiceInterface.php new file mode 100644 index 000000000..b066fe310 --- /dev/null +++ b/src/Components/Ratepay/DeviceFingerprint/DeviceFingerprintServiceInterface.php @@ -0,0 +1,18 @@ +cartService = $cartService; + $this->client = $client; + $this->requestParameterFactory = $requestParameterFactory; + $this->profileService = $profileService; + } + + public function getInstallmentCalculatorData(SalesChannelContext $salesChannelContext, ?RequestDataBag $dataBag = null): ?RatepayInstallmentCalculatorData + { + $profile = $this->profileService->getProfileBySalesChannelContext( + $salesChannelContext, + PayoneRatepayInstallmentPaymentHandler::class + ); + + if ($profile === null) { + return null; + } + + $profileConfiguration = $profile->getConfiguration(); + $allowedMonths = explode(',', $profileConfiguration['month-allowed']); + + if (\count($allowedMonths) === 0) { + return null; + } + + $defaults = [ + 'type' => CalculationRequestParameterBuilder::INSTALLMENT_TYPE_TIME, + 'value' => $allowedMonths[0], + ]; + + if ($dataBag === null) { + $dataBag = new RequestDataBag(); + } + + if (!$dataBag->has('ratepayInstallmentType') || !$dataBag->has('ratepayInstallmentValue')) { + $dataBag->set('ratepayInstallmentType', $defaults['type']); + $dataBag->set('ratepayInstallmentValue', $defaults['value']); + } + + $calculationResponse = $this->getCalculation($dataBag, $profile, $salesChannelContext); + + $data = new RatepayInstallmentCalculatorData(); + $data->assign([ + 'minimumRate' => (float) $profileConfiguration['interestrate-min'], + 'maximumRate' => (float) $profileConfiguration['interestrate-max'], + 'allowedMonths' => $allowedMonths, + 'defaults' => $defaults, + 'calculationParams' => $dataBag->all(), + 'calculationResponse' => $calculationResponse, + ]); + + return $data; + } + + protected function getCalculation(RequestDataBag $dataBag, Profile $profile, SalesChannelContext $context): array + { + $cart = $this->cartService->getCart($context->getToken(), $context); + + $calculationRequest = $this->requestParameterFactory->getRequestParameter( + new RatepayCalculationStruct( + $cart, + $dataBag, + $context, + $profile, + PayoneRatepayInstallmentPaymentHandler::class, + AbstractRequestParameterBuilder::REQUEST_ACTION_RATEPAY_CALCULATION + ) + ); + + return $this->client->request($calculationRequest); + } +} diff --git a/src/Components/Ratepay/Installment/InstallmentServiceInterface.php b/src/Components/Ratepay/Installment/InstallmentServiceInterface.php new file mode 100644 index 000000000..da335c944 --- /dev/null +++ b/src/Components/Ratepay/Installment/InstallmentServiceInterface.php @@ -0,0 +1,14 @@ +shopId; + } + + public function setShopId(int $shopId): void + { + $this->shopId = $shopId; + } + + public function getConfiguration(): array + { + return $this->configuration; + } + + public function setConfiguration(array $configuration): void + { + $this->configuration = $configuration; + } +} diff --git a/src/Components/Ratepay/Profile/ProfileSearch.php b/src/Components/Ratepay/Profile/ProfileSearch.php new file mode 100644 index 000000000..003904313 --- /dev/null +++ b/src/Components/Ratepay/Profile/ProfileSearch.php @@ -0,0 +1,99 @@ +billingCountryCode; + } + + public function setBillingCountryCode(string $billingCountryCode): void + { + $this->billingCountryCode = $billingCountryCode; + } + + public function getShippingCountryCode(): string + { + return $this->shippingCountryCode; + } + + public function setShippingCountryCode(string $shippingCountryCode): void + { + $this->shippingCountryCode = $shippingCountryCode; + } + + public function getPaymentHandler(): string + { + return $this->paymentHandler; + } + + public function setPaymentHandler(string $paymentHandler): void + { + $this->paymentHandler = $paymentHandler; + } + + public function getSalesChannelId(): ?string + { + return $this->salesChannelId; + } + + public function setSalesChannelId(?string $salesChannelId): void + { + $this->salesChannelId = $salesChannelId; + } + + public function getCurrency(): string + { + return $this->currency; + } + + public function setCurrency(string $currency): void + { + $this->currency = $currency; + } + + public function isNeedsAllowDifferentAddress(): bool + { + return $this->needsAllowDifferentAddress; + } + + public function setNeedsAllowDifferentAddress(bool $needsAllowDifferentAddress): void + { + $this->needsAllowDifferentAddress = $needsAllowDifferentAddress; + } + + public function getTotalAmount(): float + { + return $this->totalAmount; + } + + public function setTotalAmount(float $totalAmount): void + { + $this->totalAmount = $totalAmount; + } +} diff --git a/src/Components/Ratepay/Profile/ProfileService.php b/src/Components/Ratepay/Profile/ProfileService.php new file mode 100644 index 000000000..0876874cb --- /dev/null +++ b/src/Components/Ratepay/Profile/ProfileService.php @@ -0,0 +1,240 @@ + 'elv', + PayoneRatepayInstallmentPaymentHandler::class => 'installment', + PayoneRatepayInvoicingPaymentHandler::class => 'invoice', + ]; + + /** @var PayoneClientInterface */ + private $client; + + /** @var RequestParameterFactory */ + private $requestParameterFactory; + + /** @var SystemConfigService */ + private $systemConfigService; + + /** @var OrderFetcherInterface */ + private $orderFetcher; + + /** @var CartService */ + private $cartService; + + public function __construct( + PayoneClientInterface $client, + RequestParameterFactory $requestParameterFactory, + SystemConfigService $systemConfigService, + OrderFetcherInterface $orderFetcher, + CartService $cartService + ) { + $this->client = $client; + $this->requestParameterFactory = $requestParameterFactory; + $this->systemConfigService = $systemConfigService; + $this->orderFetcher = $orderFetcher; + $this->cartService = $cartService; + } + + public function getProfile(ProfileSearch $profileSearch): ?Profile + { + $paymentKey = self::PAYMENT_KEYS[$profileSearch->getPaymentHandler()]; + + $profileConfiguration = $this->systemConfigService->get( + ConfigReader::getConfigKeyByPaymentHandler($profileSearch->getPaymentHandler(), 'ProfileConfigurations'), + $profileSearch->getSalesChannelId() + ); + + if ($profileConfiguration === null) { + return null; + } + + foreach ($profileConfiguration as $shopId => $configuration) { + if ($profileSearch->isNeedsAllowDifferentAddress() && $configuration['delivery-address-' . $paymentKey] !== 'yes') { + continue; + } + + $allowedBillingCountries = explode(',', $configuration['country-code-billing']); + + if (!in_array($profileSearch->getBillingCountryCode(), $allowedBillingCountries, true)) { + continue; + } + + $allowedDeliveryCountries = explode(',', $configuration['country-code-delivery']); + + if (!in_array($profileSearch->getShippingCountryCode(), $allowedDeliveryCountries, true)) { + continue; + } + + $allowedCurrencies = explode(',', $configuration['currency']); + + if (!in_array($profileSearch->getCurrency(), $allowedCurrencies, true)) { + continue; + } + + if ($profileSearch->getTotalAmount() > $configuration['tx-limit-' . $paymentKey . '-max']) { + continue; + } + + if ($profileSearch->getTotalAmount() < $configuration['tx-limit-' . $paymentKey . '-min']) { + continue; + } + + $profile = new Profile(); + $profile->setShopId($shopId); + $profile->setConfiguration($configuration); + + return $profile; + } + + return null; + } + + public function getProfileByOrder(OrderEntity $order, string $paymentHandler): ?Profile + { + $billingAddress = $this->orderFetcher->getOrderBillingAddress($order); + $shippingAddress = $this->orderFetcher->getOrderShippingAddress($order); + + $billingCountry = $billingAddress->getCountry(); + $shippingCountry = $shippingAddress->getCountry(); + $currency = $order->getCurrency(); + + if ($billingCountry === null || $shippingCountry === null || $currency === null) { + return null; + } + + $profileSearch = new ProfileSearch(); + $profileSearch->setBillingCountryCode($billingCountry->getIso()); + $profileSearch->setShippingCountryCode($shippingCountry->getIso()); + $profileSearch->setPaymentHandler($paymentHandler); + $profileSearch->setSalesChannelId($order->getSalesChannelId()); + $profileSearch->setCurrency($currency->getIsoCode()); + $profileSearch->setNeedsAllowDifferentAddress(!AddressCompare::areOrderAddressesIdentical($billingAddress, $shippingAddress)); + $profileSearch->setTotalAmount($order->getPrice()->getTotalPrice()); + + return $this->getProfile($profileSearch); + } + + public function getProfileBySalesChannelContext(SalesChannelContext $salesChannelContext, string $paymentHandler): ?Profile + { + $customer = $salesChannelContext->getCustomer(); + + if ($customer === null) { + return null; + } + + $billingAddress = $customer->getActiveBillingAddress(); + $shippingAddress = $customer->getActiveShippingAddress(); + + if ($billingAddress === null || $shippingAddress === null) { + return null; + } + + $billingCountry = $billingAddress->getCountry(); + $shippingCountry = $shippingAddress->getCountry(); + + if ($billingCountry === null || $shippingCountry === null) { + return null; + } + + $cart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext); + + $profileSearch = new ProfileSearch(); + $profileSearch->setBillingCountryCode($billingCountry->getIso()); + $profileSearch->setShippingCountryCode($shippingCountry->getIso()); + $profileSearch->setPaymentHandler($paymentHandler); + $profileSearch->setSalesChannelId($salesChannelContext->getSalesChannelId()); + $profileSearch->setCurrency($salesChannelContext->getCurrency()->getIsoCode()); + $profileSearch->setNeedsAllowDifferentAddress(!AddressCompare::areCustomerAddressesIdentical($billingAddress, $shippingAddress)); + $profileSearch->setTotalAmount($cart->getPrice()->getTotalPrice()); + + return $this->getProfile($profileSearch); + } + + public function updateProfileConfiguration(string $paymentHandler, ?string $salesChannelId = null): array + { + $profilesConfigKey = ConfigReader::getConfigKeyByPaymentHandler($paymentHandler, 'Profiles'); + $profileConfigurationsKey = ConfigReader::getConfigKeyByPaymentHandler($paymentHandler, 'ProfileConfigurations'); + + $configUpdates = []; + $errors = []; + + $profiles = $this->systemConfigService->get($profilesConfigKey, $salesChannelId); + + $validProfiles = []; + $configurationResponses = []; + foreach ($profiles as $profile) { + $shopId = (int) $profile['shopId']; + $currency = $profile['currency']; + + if ($shopId === 0 || empty($currency)) { + $profile['error'] = 'Shop ID or Currency missing'; + $errors[$profilesConfigKey][] = $profile; + + continue; + } + + $profileRequest = $this->requestParameterFactory->getRequestParameter( + new RatepayProfileStruct( + $shopId, + $currency, + $salesChannelId ?? '', + $paymentHandler, + AbstractRequestParameterBuilder::REQUEST_ACTION_RATEPAY_PROFILE + ) + ); + + try { + $response = $this->client->request($profileRequest); + } catch (PayoneRequestException $exception) { + $profile['error'] = $exception->getResponse()['error']['ErrorMessage']; + $errors[$profilesConfigKey][] = $profile; + + continue; + } + + $configurationResponses[$shopId] = $response['addpaydata']; + $validProfiles[$shopId] = $profile; + } + + $validProfiles = array_values($validProfiles); + $this->systemConfigService->set( + $profilesConfigKey, + $validProfiles, + $salesChannelId + ); + $this->systemConfigService->set( + $profileConfigurationsKey, + $configurationResponses, + $salesChannelId + ); + $configUpdates[$profilesConfigKey] = $validProfiles; + $configUpdates[$profileConfigurationsKey] = $configurationResponses; + + return [ + 'updates' => $configUpdates, + 'errors' => $errors, + ]; + } +} diff --git a/src/Components/Ratepay/Profile/ProfileServiceInterface.php b/src/Components/Ratepay/Profile/ProfileServiceInterface.php new file mode 100644 index 000000000..8761e45e9 --- /dev/null +++ b/src/Components/Ratepay/Profile/ProfileServiceInterface.php @@ -0,0 +1,19 @@ + 'PAYONE_INVALID_COUNTRY_CODE_ERROR', + self::INVALID_CHARACTERS_ERROR => 'PAYONE_INVALID_CHARACTERS_ERROR', + self::CHECKSUM_FAILED_ERROR => 'PAYONE_CHECKSUM_FAILED_ERROR', + self::INVALID_FORMAT_ERROR => 'PAYONE_INVALID_FORMAT_ERROR', + self::NOT_SUPPORTED_COUNTRY_CODE_ERROR => 'PAYONE_NOT_SUPPORTED_COUNTRY_CODE_ERROR', + ]; + + public function validatedBy(): string + { + return IbanValidator::class; + } +} diff --git a/src/Configuration/ConfigurationPrefixes.php b/src/Configuration/ConfigurationPrefixes.php index 5ac77a510..1a717abf0 100644 --- a/src/Configuration/ConfigurationPrefixes.php +++ b/src/Configuration/ConfigurationPrefixes.php @@ -25,6 +25,9 @@ interface ConfigurationPrefixes public const CONFIGURATION_PREFIX_OPEN_INVOICE = 'openInvoice'; public const CONFIGURATION_PREFIX_APPLE_PAY = 'applePay'; public const CONFIGURATION_PREFIX_BANCONTACT = 'bancontact'; + public const CONFIGURATION_PREFIX_RATEPAY_DEBIT = 'ratepayDebit'; + public const CONFIGURATION_PREFIX_RATEPAY_INSTALLMENT = 'ratepayInstallment'; + public const CONFIGURATION_PREFIX_RATEPAY_INVOICING = 'ratepayInvoicing'; public const CONFIGURATION_PREFIXES = [ Handler\PayoneApplePayPaymentHandler::class => self::CONFIGURATION_PREFIX_APPLE_PAY, @@ -44,5 +47,8 @@ interface ConfigurationPrefixes Handler\PayoneSecureInvoicePaymentHandler::class => self::CONFIGURATION_PREFIX_SECURE_INVOICE, Handler\PayoneOpenInvoicePaymentHandler::class => self::CONFIGURATION_PREFIX_OPEN_INVOICE, Handler\PayoneBancontactPaymentHandler::class => self::CONFIGURATION_PREFIX_BANCONTACT, + Handler\PayoneRatepayDebitPaymentHandler::class => self::CONFIGURATION_PREFIX_RATEPAY_DEBIT, + Handler\PayoneRatepayInstallmentPaymentHandler::class => self::CONFIGURATION_PREFIX_RATEPAY_INSTALLMENT, + Handler\PayoneRatepayInvoicingPaymentHandler::class => self::CONFIGURATION_PREFIX_RATEPAY_INVOICING, ]; } diff --git a/src/Controller/SettingsController.php b/src/Controller/SettingsController.php index f7abd487c..87146be0b 100644 --- a/src/Controller/SettingsController.php +++ b/src/Controller/SettingsController.php @@ -79,7 +79,7 @@ public function validateApiCredentials(Request $request, Context $context): Json $criteria = (new Criteria())->addFilter(new EqualsFilter('handlerIdentifier', $paymentClass)); $paymentMethod = $paymentMethodRepository->search($criteria, $context)->first(); - if (!$paymentMethod || !$paymentMethod->getActive()) { + if (!$paymentMethod || !$paymentMethod->getActive() || in_array($paymentMethod->getHandlerIdentifier(), Handler\PaymentHandlerGroups::RATEPAY, true)) { continue; } @@ -384,7 +384,7 @@ private function getPaymentParameters(string $paymentClass): array 'businessrelation' => 'b2c', ]; - case Handler\PayoneOpenInvoicePaymentHandler::class: + case Handler\PayoneOpenInvoicePaymentHandler::class: return [ 'request' => 'preauthorization', 'clearingtype' => 'rec', diff --git a/src/Core/Utils/AddressCompare.php b/src/Core/Utils/AddressCompare.php new file mode 100644 index 000000000..36b339f54 --- /dev/null +++ b/src/Core/Utils/AddressCompare.php @@ -0,0 +1,61 @@ +get($field) !== $entity2->get($field)) { + return false; + } + } + + return true; + } +} diff --git a/src/DependencyInjection/controllers.xml b/src/DependencyInjection/controllers.xml index d01238515..393a1c959 100644 --- a/src/DependencyInjection/controllers.xml +++ b/src/DependencyInjection/controllers.xml @@ -66,6 +66,16 @@ + + + + + + + + + @@ -105,5 +115,13 @@ + + + + + + + + diff --git a/src/DependencyInjection/handler/payment_handler.xml b/src/DependencyInjection/handler/payment_handler.xml index 8b8f2cec1..0f4e6754b 100644 --- a/src/DependencyInjection/handler/payment_handler.xml +++ b/src/DependencyInjection/handler/payment_handler.xml @@ -218,5 +218,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DependencyInjection/listeners.xml b/src/DependencyInjection/listeners.xml index 00214f890..32e1302fd 100644 --- a/src/DependencyInjection/listeners.xml +++ b/src/DependencyInjection/listeners.xml @@ -29,6 +29,14 @@ + + + + + + + + @@ -56,7 +64,7 @@ - + @@ -86,5 +94,10 @@ + + + + + diff --git a/src/DependencyInjection/requestParameter/builder.xml b/src/DependencyInjection/requestParameter/builder.xml index 447964a87..c894bc5e3 100644 --- a/src/DependencyInjection/requestParameter/builder.xml +++ b/src/DependencyInjection/requestParameter/builder.xml @@ -366,6 +366,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DependencyInjection/services.xml b/src/DependencyInjection/services.xml index fdc41489e..cdda33be1 100644 --- a/src/DependencyInjection/services.xml +++ b/src/DependencyInjection/services.xml @@ -67,5 +67,24 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/EventListener/CheckoutConfirmRatepayEventListener.php b/src/EventListener/CheckoutConfirmRatepayEventListener.php new file mode 100644 index 000000000..8f8ccd6e7 --- /dev/null +++ b/src/EventListener/CheckoutConfirmRatepayEventListener.php @@ -0,0 +1,201 @@ +systemConfigService = $systemConfigService; + $this->installmentService = $installmentService; + $this->deviceFingerprintService = $deviceFingerprintService; + $this->profileService = $profileService; + } + + public static function getSubscribedEvents(): array + { + return [ + CheckoutConfirmPageLoadedEvent::class => [ + ['hidePaymentMethodsForCompanies'], + ['hidePaymentMethodsByProfiles'], + ['addPayonePageData'], + ], + AccountEditOrderPageLoadedEvent::class => [ + ['hidePaymentMethodsForCompanies'], + ['hidePaymentMethodsByProfiles'], + ['addPayonePageData'], + ], + AccountPaymentMethodPageLoadedEvent::class => 'hidePaymentMethodsForCompanies', + ]; + } + + public function hidePaymentMethodsForCompanies(PageLoadedEvent $event): void + { + $page = $event->getPage(); + + if ( + !method_exists($page, 'getPaymentMethods') || + !method_exists($page, 'setPaymentMethods') + ) { + return; + } + + if (!$this->customerHasCompanyAddress($event->getSalesChannelContext())) { + return; + } + + $paymentMethods = $this->removePaymentMethods($page->getPaymentMethods(), PaymentHandlerGroups::RATEPAY); + + $page->setPaymentMethods($paymentMethods); + } + + public function hidePaymentMethodsByProfiles(PageLoadedEvent $event): void + { + $page = $event->getPage(); + + if ( + !method_exists($page, 'getPaymentMethods') || + !method_exists($page, 'setPaymentMethods') + ) { + return; + } + + $paymentMethods = $page->getPaymentMethods(); + + foreach (PaymentHandlerGroups::RATEPAY as $ratepayPaymentHandler) { + $profile = $this->profileService->getProfileBySalesChannelContext( + $event->getSalesChannelContext(), + $ratepayPaymentHandler + ); + + if (!$profile) { + $paymentMethods = $this->removePaymentMethods($paymentMethods, [$ratepayPaymentHandler]); + } + } + + $page->setPaymentMethods($paymentMethods); + } + + public function addPayonePageData(PageLoadedEvent $event): void + { + $page = $event->getPage(); + $context = $event->getSalesChannelContext(); + + if ($context->getPaymentMethod()->getId() === PayoneRatepayInstallment::UUID) { + $this->addInstallmentCalculatorData($page, $context); + } + + if (in_array($context->getPaymentMethod()->getHandlerIdentifier(), PaymentHandlerGroups::RATEPAY, true)) { + $this->addDeviceFingerprintData($page, $context); + } + } + + protected function removePaymentMethods(PaymentMethodCollection $paymentMethods, array $paymentHandler): PaymentMethodCollection + { + return $paymentMethods->filter( + static function (PaymentMethodEntity $paymentMethod) use ($paymentHandler) { + return !in_array($paymentMethod->getHandlerIdentifier(), $paymentHandler, true); + } + ); + } + + protected function customerHasCompanyAddress(SalesChannelContext $context): bool + { + $customer = $context->getCustomer(); + + if (null === $customer) { + return false; + } + + $billingAddress = $customer->getActiveBillingAddress(); + + if (null === $billingAddress) { + return false; + } + + return !empty($billingAddress->getCompany()); + } + + protected function addInstallmentCalculatorData(Page $page, SalesChannelContext $context): void + { + if ( + !method_exists($page, 'getPaymentMethods') || + !method_exists($page, 'setPaymentMethods') + ) { + return; + } + + $installmentCalculator = $this->installmentService->getInstallmentCalculatorData($context); + + if ($installmentCalculator === null) { + $paymentMethods = $this->removePaymentMethods($page->getPaymentMethods(), [ + PayoneRatepayInstallmentPaymentHandler::class, + ]); + $page->setPaymentMethods($paymentMethods); + + return; + } + + $page->addExtension(RatepayInstallmentCalculatorData::EXTENSION_NAME, $installmentCalculator); + } + + protected function addDeviceFingerprintData(Page $page, SalesChannelContext $context): void + { + if ($this->deviceFingerprintService->isDeviceIdentTokenAlreadyGenerated() === false) { + $snippetId = $this->systemConfigService->get( + ConfigReader::getConfigKeyByPaymentHandler( + PayoneRatepayInvoicingPaymentHandler::class, + 'DeviceFingerprintSnippetId' + ), + $context->getSalesChannelId() + ) ?? 'ratepay'; + + $deviceIdentToken = $this->deviceFingerprintService->getDeviceIdentToken(); + $snippet = $this->deviceFingerprintService->getDeviceIdentSnippet($snippetId, $deviceIdentToken); + + $extension = new RatepayDeviceFingerprintData(); + $extension->setSnippet($snippet); + + $page->addExtension(RatepayDeviceFingerprintData::EXTENSION_NAME, $extension); + } + } +} diff --git a/src/EventListener/KernelEventListener.php b/src/EventListener/KernelEventListener.php new file mode 100644 index 000000000..1ba6876dd --- /dev/null +++ b/src/EventListener/KernelEventListener.php @@ -0,0 +1,90 @@ +profileService = $profileService; + } + + public static function getSubscribedEvents(): array + { + return [ + ResponseEvent::class => 'onKernelResponse', + ]; + } + + public function onKernelResponse(ResponseEvent $event): void + { + $route = $event->getRequest()->get('_route'); + $response = $event->getResponse(); + + if ($route === 'api.action.core.save.system-config.batch') { + $results = []; + $configurations = $event->getRequest()->request->all(); + + foreach ($configurations as $salesChannelId => $configuration) { + foreach (PaymentHandlerGroups::RATEPAY as $ratepayHandler) { + $profilesConfigKey = ConfigReader::getConfigKeyByPaymentHandler($ratepayHandler, 'Profiles'); + + if (isset($configuration[$profilesConfigKey])) { + $result = $this->profileService->updateProfileConfiguration( + $ratepayHandler, + $salesChannelId === 'null' ? null : $salesChannelId + ); + $results[$salesChannelId][] = $result; + } + } + } + + if ($response instanceof JsonResponse && count($results) > 0) { + $this->setResponseData($response, $results); + } + } + } + + protected function setResponseData(JsonResponse $response, array $updateResults): void + { + $data = []; + + if ($response->getContent()) { + $data = json_decode($response->getContent(), true); + } + + $data['payoneRatepayProfilesUpdateResult'] = []; + foreach ($updateResults as $salesChannelId => $updateResultsBySalesChannel) { + $salesChannelData = [ + 'updates' => [], + 'errors' => [], + ]; + + foreach ($updateResultsBySalesChannel as $updateResult) { + $salesChannelData['updates'][] = $updateResult['updates']; + $salesChannelData['errors'][] = $updateResult['errors']; + } + + $salesChannelData['updates'] = array_merge(...$salesChannelData['updates']); + $salesChannelData['errors'] = array_merge(...$salesChannelData['errors']); + + $data['payoneRatepayProfilesUpdateResult'][$salesChannelId] = $salesChannelData; + } + + $response->setData($data); + $response->setStatusCode(Response::HTTP_OK); + } +} diff --git a/src/EventListener/OrderValidationEventListener.php b/src/EventListener/OrderValidationEventListener.php index dfea3e4f3..e715581e7 100644 --- a/src/EventListener/OrderValidationEventListener.php +++ b/src/EventListener/OrderValidationEventListener.php @@ -4,35 +4,28 @@ namespace PayonePayment\EventListener; -use DateTime; -use DateTimeInterface; -use PayonePayment\Components\ConfigReader\ConfigReaderInterface; -use PayonePayment\Components\Validator\Birthday; -use PayonePayment\Components\Validator\PaymentMethod; -use PayonePayment\PaymentMethod\PayoneOpenInvoice; -use PayonePayment\PaymentMethod\PayonePayolutionInstallment; -use PayonePayment\PaymentMethod\PayonePayolutionInvoicing; -use PayonePayment\PaymentMethod\PayoneSecureInvoice; +use PayonePayment\PaymentHandler\AbstractPayonePaymentHandler; +use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\PaymentHandlerRegistry; use Shopware\Core\Framework\Validation\BuildValidationEvent; +use Shopware\Core\Framework\Validation\DataValidationDefinition; use Shopware\Core\PlatformRequest; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Validator\Constraints\NotBlank; class OrderValidationEventListener implements EventSubscriberInterface { /** @var RequestStack */ private $requestStack; - /** @var ConfigReaderInterface */ - private $configReader; + /** @var PaymentHandlerRegistry */ + private $paymentHandlerRegistry; - public function __construct(RequestStack $requestStack, ConfigReaderInterface $configReader) + public function __construct(RequestStack $requestStack, PaymentHandlerRegistry $paymentHandlerRegistry) { - $this->requestStack = $requestStack; - $this->configReader = $configReader; + $this->requestStack = $requestStack; + $this->paymentHandlerRegistry = $paymentHandlerRegistry; } public static function getSubscribedEvents(): array @@ -50,133 +43,32 @@ public function validateOrderData(BuildValidationEvent $event): void return; } - $context = $this->getContextFromRequest($request); + $salesChannelContext = $this->getSalesChannelContextFromRequest($request); + $paymentHandlerIdentifier = $salesChannelContext->getPaymentMethod()->getHandlerIdentifier(); + $paymentHandler = $this->paymentHandlerRegistry->getHandler($paymentHandlerIdentifier); - $this->addInvoiceValidationDefinitions($context, $event); - $this->addPayolutionInvoicingValidationDefinitions($context, $event); - $this->addPayolutionInstallmentValidationDefinitions($context, $event); - } - - private function addInvoiceValidationDefinitions(SalesChannelContext $salesChannelContext, BuildValidationEvent $event): void - { - $customer = $salesChannelContext->getCustomer(); - - if (null === $customer) { - return; - } - - if ($this->isInvoicePayment($salesChannelContext) === false) { - return; - } - - $activeBilling = $customer->getActiveBillingAddress(); - - if ($activeBilling !== null && empty($activeBilling->getCompany())) { - $event->getDefinition()->add( - 'payoneInvoiceBirthday', - new Birthday(['value' => $this->getMinimumDate()]) - ); - } - } - - private function addPayolutionInvoicingValidationDefinitions(SalesChannelContext $salesChannelContext, BuildValidationEvent $event): void - { - if ($this->isPayonePayolutionInvoicing($salesChannelContext) === false) { - return; - } - - $event->getDefinition()->add( - 'payolutionConsent', - new NotBlank() - ); - - $event->getDefinition()->add( - 'payolutionBirthday', - new Birthday(['value' => $this->getMinimumDate()]) - ); - - if ($this->companyDataHandlingIsDisabled($salesChannelContext) === false) { - return; - } - - if ($this->customerHasCompanyAddress($salesChannelContext)) { - $event->getDefinition()->add( - 'payonePaymentMethod', - new PaymentMethod(['value' => $salesChannelContext->getPaymentMethod()]) - ); - } - } - - private function addPayolutionInstallmentValidationDefinitions(SalesChannelContext $salesChannelContext, BuildValidationEvent $event): void - { - if ($this->isPayonePayolutionInstallment($salesChannelContext) === false) { - return; - } - - $event->getDefinition()->add( - 'payolutionConsent', - new NotBlank() - ); + if ($paymentHandler instanceof AbstractPayonePaymentHandler) { + $validationDefinitions = $paymentHandler->getValidationDefinitions($salesChannelContext); - $event->getDefinition()->add( - 'payolutionBirthday', - new Birthday(['value' => $this->getMinimumDate()]) - ); - - if ($this->customerHasCompanyAddress($salesChannelContext)) { - $event->getDefinition()->add( - 'payonePaymentMethod', - new PaymentMethod(['value' => $salesChannelContext->getPaymentMethod()]) - ); + if ($validationDefinitions !== []) { + $this->addSubConstraints($event->getDefinition(), $validationDefinitions); + } } } - private function getMinimumDate(): DateTimeInterface - { - return (new DateTime())->modify('-18 years')->setTime(0, 0); - } - - private function getContextFromRequest(Request $request): SalesChannelContext + private function getSalesChannelContextFromRequest(Request $request): SalesChannelContext { return $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT); } - private function isPayonePayolutionInstallment(SalesChannelContext $context): bool - { - return $context->getPaymentMethod()->getId() === PayonePayolutionInstallment::UUID; - } - - private function isPayonePayolutionInvoicing(SalesChannelContext $context): bool - { - return $context->getPaymentMethod()->getId() === PayonePayolutionInvoicing::UUID; - } - - private function isInvoicePayment(SalesChannelContext $context): bool - { - return in_array($context->getPaymentMethod()->getId(), [PayoneSecureInvoice::UUID, PayoneOpenInvoice::UUID]); - } - - private function customerHasCompanyAddress(SalesChannelContext $context): bool + private function addSubConstraints(DataValidationDefinition $parent, array $children): void { - $customer = $context->getCustomer(); - - if (null === $customer) { - return false; + foreach ($children as $key => $constraints) { + if ($constraints instanceof DataValidationDefinition) { + $parent->addSub($key, $constraints); + } else { + call_user_func_array([$parent, 'add'], array_merge([$key], $constraints)); + } } - - $billingAddress = $customer->getActiveBillingAddress(); - - if (null === $billingAddress) { - return false; - } - - return !empty($billingAddress->getCompany()); - } - - private function companyDataHandlingIsDisabled(SalesChannelContext $context): bool - { - $configuration = $this->configReader->read($context->getSalesChannel()->getId()); - - return !((bool) $configuration->get('payolutionInvoicingTransferCompanyData')); } } diff --git a/src/Installer/CustomFieldInstaller.php b/src/Installer/CustomFieldInstaller.php index 5f2eb5cc9..c7dadf1a0 100644 --- a/src/Installer/CustomFieldInstaller.php +++ b/src/Installer/CustomFieldInstaller.php @@ -35,10 +35,13 @@ class CustomFieldInstaller implements InstallerInterface public const CAPTURED_QUANTITY = 'payone_captured_quantity'; public const REFUNDED_QUANTITY = 'payone_refunded_quantity'; public const CLEARING_BANK_ACCOUNT = 'payone_clearing_bank_account'; + public const CUSTOMER_PHONE_NUMBER = 'payone_customer_phone_number'; + public const USED_RATEPAY_SHOP_ID = 'payone_used_ratepay_shop_id'; public const FIELDSET_ID_ORDER_TRANSACTION = 'aacbcf9bedfb4827853b75c5fd278d3f'; public const FIELDSET_ID_ORDER_LINE_ITEM = '12f3f06c895e11eabc550242ac130003'; public const FIELDSET_ID_PAYMENT_METHOD = 'ed39626e94fd4dfe9d81976fdbcdb06c'; + public const FIELDSET_ID_CUSTOMER = '8e4a0b8f7eb04272ad874f3b22cf4935'; /** @var EntityRepositoryInterface */ private $customFieldRepository; @@ -100,6 +103,21 @@ public function __construct(EntityRepositoryInterface $customFieldSetRepository, 'entityName' => 'order_line_item', ], ], + [ + 'id' => self::FIELDSET_ID_CUSTOMER, + 'name' => 'customer_payone_payment', + 'config' => [ + 'label' => [ + 'en-GB' => 'PAYONE', + 'de-DE' => 'PAYONE', + ], + 'translated' => true, + ], + 'relation' => [ + 'id' => '4b23593512f848d8ba360985de234a1b', + 'entityName' => 'customer', + ], + ], ]; $this->customFields = [ @@ -205,6 +223,12 @@ public function __construct(EntityRepositoryInterface $customFieldSetRepository, 'type' => CustomFieldTypes::TEXT, 'customFieldSetId' => self::FIELDSET_ID_ORDER_TRANSACTION, ], + [ + 'id' => '0beeb4fd0c4947afaa360cb0431c29ad', + 'name' => self::USED_RATEPAY_SHOP_ID, + 'type' => CustomFieldTypes::INT, + 'customFieldSetId' => self::FIELDSET_ID_ORDER_TRANSACTION, + ], [ 'id' => 'e3583a4c893611eabc550242ac130003', 'name' => self::CAPTURED_QUANTITY, @@ -223,6 +247,25 @@ public function __construct(EntityRepositoryInterface $customFieldSetRepository, 'type' => CustomFieldTypes::JSON, 'customFieldSetId' => self::FIELDSET_ID_ORDER_TRANSACTION, ], + [ + 'id' => 'e56cc871e9784c3b91dd755511dc0221', + 'name' => self::CUSTOMER_PHONE_NUMBER, + 'type' => CustomFieldTypes::TEXT, + 'customFieldSetId' => self::FIELDSET_ID_CUSTOMER, + 'config' => [ + 'componentName' => 'sw-field', + 'customFieldType' => CustomFieldTypes::TEXT, + 'type' => CustomFieldTypes::TEXT, + 'label' => [ + 'en-GB' => 'Phone Number', + 'de-DE' => 'Telefonnummer', + ], + 'helpText' => [ + 'en-GB' => 'Will be asked for some PAYONE payment methods in the checkout and stored in this field after the first time. After that, the saved phone number is always used and it is no longer requested.', + 'de-DE' => 'Wird bei manchen PAYONE Zahlungsarten im Checkout abgefragt und nach dem ersten mal in diesem Feld gespeichert. Danach wird immer die gespeicherte Telefonnummer verwendet und sie wird nicht mehr abgefragt.', + ], + ], + ], ]; } @@ -284,6 +327,7 @@ private function upsertCustomField(array $customField, Context $context): void 'type' => $customField['type'], 'active' => true, 'customFieldSetId' => $customField['customFieldSetId'], + 'config' => $customField['config'] ?? [], ]; $this->customFieldRepository->upsert([$data], $context); diff --git a/src/Installer/PaymentMethodInstaller.php b/src/Installer/PaymentMethodInstaller.php index 0a9304cc4..a392c920d 100644 --- a/src/Installer/PaymentMethodInstaller.php +++ b/src/Installer/PaymentMethodInstaller.php @@ -20,6 +20,9 @@ use PayonePayment\PaymentMethod\PayonePaypal; use PayonePayment\PaymentMethod\PayonePaypalExpress; use PayonePayment\PaymentMethod\PayonePrepayment; +use PayonePayment\PaymentMethod\PayoneRatepayDebit; +use PayonePayment\PaymentMethod\PayoneRatepayInstallment; +use PayonePayment\PaymentMethod\PayoneRatepayInvoicing; use PayonePayment\PaymentMethod\PayoneSecureInvoice; use PayonePayment\PaymentMethod\PayoneSofortBanking; use PayonePayment\PaymentMethod\PayoneTrustly; @@ -56,6 +59,9 @@ class PaymentMethodInstaller implements InstallerInterface PayoneSecureInvoice::class => '4e8a9d3d3c6e428887573856b38c9003', PayoneOpenInvoice::class => '9024aa5a502b4544a745b6b64b486e21', PayoneBancontact::class => '32ecec740c7142c9bf51d00ea894ffad', + PayoneRatepayDebit::class => '48f2034b3c62480a8554781cf9cac574', + PayoneRatepayInstallment::class => '0af0f201fd164ca9ae72313c70201d18', + PayoneRatepayInvoicing::class => '240dcc8bf5fc409c9dcf840698c082aa', ]; public const HANDLER_IDENTIFIER_ROOT_NAMESPACE = 'PayonePayment'; @@ -78,6 +84,9 @@ class PaymentMethodInstaller implements InstallerInterface PayoneSecureInvoice::class, PayoneOpenInvoice::class, PayoneBancontact::class, + PayoneRatepayDebit::class, + PayoneRatepayInstallment::class, + PayoneRatepayInvoicing::class, ]; public const AFTER_ORDER_PAYMENT_METHODS = [ @@ -94,6 +103,9 @@ class PaymentMethodInstaller implements InstallerInterface PayonePaydirekt::class, PayonePrepayment::class, PayoneTrustly::class, + PayoneRatepayDebit::class, + PayoneRatepayInstallment::class, + PayoneRatepayInvoicing::class, ]; /** @var PluginIdProvider */ diff --git a/src/PaymentHandler/AbstractPayoneInvoicePaymentHandler.php b/src/PaymentHandler/AbstractPayoneInvoicePaymentHandler.php index f94afa25e..974310ba9 100644 --- a/src/PaymentHandler/AbstractPayoneInvoicePaymentHandler.php +++ b/src/PaymentHandler/AbstractPayoneInvoicePaymentHandler.php @@ -6,6 +6,7 @@ use PayonePayment\Components\ConfigReader\ConfigReaderInterface; use PayonePayment\Components\DataHandler\Transaction\TransactionDataHandlerInterface; +use PayonePayment\Components\Validator\Birthday; use PayonePayment\Installer\CustomFieldInstaller; use PayonePayment\Payone\Client\Exception\PayoneRequestException; use PayonePayment\Payone\Client\PayoneClientInterface; @@ -19,6 +20,7 @@ use Shopware\Core\Framework\Validation\DataBag\RequestDataBag; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Contracts\Translation\TranslatorInterface; use Throwable; @@ -124,6 +126,17 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d $this->dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); } + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + if (!$this->customerHasCompanyAddress($salesChannelContext)) { + $definitions['payoneInvoiceBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + } + + return $definitions; + } + /** * Returns the config key for self::getAuthorizationMethod() */ diff --git a/src/PaymentHandler/AbstractPayonePaymentHandler.php b/src/PaymentHandler/AbstractPayonePaymentHandler.php index 8d15022ce..310ac4ea8 100644 --- a/src/PaymentHandler/AbstractPayonePaymentHandler.php +++ b/src/PaymentHandler/AbstractPayonePaymentHandler.php @@ -12,6 +12,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\Validation\DataBag\RequestDataBag; +use Shopware\Core\System\SalesChannel\SalesChannelContext; use Symfony\Component\HttpFoundation\RequestStack; /** @@ -31,6 +32,10 @@ abstract class AbstractPayonePaymentHandler implements PayonePaymentHandlerInter public const PAYONE_FINANCING_PYS = 'PYS'; public const PAYONE_FINANCING_PYD = 'PYD'; + public const PAYONE_FINANCING_RPV = 'RPV'; + public const PAYONE_FINANCING_RPS = 'RPS'; + public const PAYONE_FINANCING_RPD = 'RPD'; + /** @var ConfigReaderInterface */ protected $configReader; @@ -50,6 +55,11 @@ public function __construct( $this->requestStack = $requestStack; } + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + return []; + } + /** * Returns true if a capture is generally not possible (or never in this context) * based on the current TX status notification. Use this method early in @@ -242,4 +252,26 @@ protected function fetchRequestData(): RequestDataBag return new RequestDataBag($request->request->all()); } + + protected function getMinimumDate(): \DateTimeInterface + { + return (new \DateTime())->modify('-18 years')->setTime(0, 0); + } + + protected function customerHasCompanyAddress(SalesChannelContext $salesChannelContext): bool + { + $customer = $salesChannelContext->getCustomer(); + + if (null === $customer) { + return false; + } + + $billingAddress = $customer->getActiveBillingAddress(); + + if (null === $billingAddress) { + return false; + } + + return !empty($billingAddress->getCompany()); + } } diff --git a/src/PaymentHandler/PaymentHandlerGroups.php b/src/PaymentHandler/PaymentHandlerGroups.php new file mode 100644 index 000000000..c07022d0c --- /dev/null +++ b/src/PaymentHandler/PaymentHandlerGroups.php @@ -0,0 +1,14 @@ +dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); } + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + $definitions['payolutionConsent'] = [new NotBlank()]; + $definitions['payolutionBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + + if ($this->customerHasCompanyAddress($salesChannelContext)) { + $definitions['payonePaymentMethod'] = [new PaymentMethod(['value' => $salesChannelContext->getPaymentMethod()])]; + } + + return $definitions; + } + /** * {@inheritdoc} */ diff --git a/src/PaymentHandler/PayonePayolutionInvoicingPaymentHandler.php b/src/PaymentHandler/PayonePayolutionInvoicingPaymentHandler.php index fea1647e5..68a7503ae 100644 --- a/src/PaymentHandler/PayonePayolutionInvoicingPaymentHandler.php +++ b/src/PaymentHandler/PayonePayolutionInvoicingPaymentHandler.php @@ -6,6 +6,8 @@ use PayonePayment\Components\ConfigReader\ConfigReaderInterface; use PayonePayment\Components\DataHandler\Transaction\TransactionDataHandlerInterface; +use PayonePayment\Components\Validator\Birthday; +use PayonePayment\Components\Validator\PaymentMethod; use PayonePayment\Installer\CustomFieldInstaller; use PayonePayment\Payone\Client\Exception\PayoneRequestException; use PayonePayment\Payone\Client\PayoneClientInterface; @@ -19,6 +21,7 @@ use Shopware\Core\Framework\Validation\DataBag\RequestDataBag; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Contracts\Translation\TranslatorInterface; use Throwable; @@ -115,6 +118,22 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d $this->dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); } + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + $definitions['payolutionConsent'] = [new NotBlank()]; + $definitions['payolutionBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + + $configuration = $this->configReader->read($salesChannelContext->getSalesChannel()->getId()); + + if (!$configuration->get('payolutionInvoicingTransferCompanyData') && $this->customerHasCompanyAddress($salesChannelContext)) { + $definitions['payonePaymentMethod'] = [new PaymentMethod(['value' => $salesChannelContext->getPaymentMethod()])]; + } + + return $definitions; + } + /** * {@inheritdoc} */ diff --git a/src/PaymentHandler/PayoneRatepayDebitPaymentHandler.php b/src/PaymentHandler/PayoneRatepayDebitPaymentHandler.php new file mode 100644 index 000000000..db1895d51 --- /dev/null +++ b/src/PaymentHandler/PayoneRatepayDebitPaymentHandler.php @@ -0,0 +1,169 @@ +client = $client; + $this->translator = $translator; + $this->dataHandler = $dataHandler; + $this->requestParameterFactory = $requestParameterFactory; + $this->deviceFingerprintService = $deviceFingerprintService; + } + + /** + * {@inheritdoc} + */ + public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $dataBag, SalesChannelContext $salesChannelContext): void + { + $requestData = $this->fetchRequestData(); + + // Get configured authorization method + $authorizationMethod = $this->getAuthorizationMethod( + $transaction->getOrder()->getSalesChannelId(), + 'ratepayDebitAuthorizationMethod', + 'preauthorization' + ); + + $paymentTransaction = PaymentTransaction::fromSyncPaymentTransactionStruct($transaction, $transaction->getOrder()); + + $request = $this->requestParameterFactory->getRequestParameter( + new PaymentTransactionStruct( + $paymentTransaction, + $requestData, + $salesChannelContext, + __CLASS__, + $authorizationMethod + ) + ); + + try { + $response = $this->client->request($request); + } catch (PayoneRequestException $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $exception->getResponse()['error']['CustomerMessage'] + ); + } catch (Throwable $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + if (empty($response['status']) || $response['status'] === 'ERROR') { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + // It differs depending on the authorization method + $clearingReference = $response['addpaydata']['clearing_reference'] ?? $response['clearing']['Reference']; + + // Prepare custom fields for the transaction + $data = $this->prepareTransactionCustomFields($request, $response, array_merge( + $this->getBaseCustomFields($response['status']), + [ + CustomFieldInstaller::WORK_ORDER_ID => $requestData->get('workorder'), + CustomFieldInstaller::CLEARING_REFERENCE => $clearingReference, + CustomFieldInstaller::CAPTURE_MODE => AbstractPayonePaymentHandler::PAYONE_STATE_COMPLETED, + CustomFieldInstaller::CLEARING_TYPE => AbstractPayonePaymentHandler::PAYONE_CLEARING_FNC, + CustomFieldInstaller::FINANCING_TYPE => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPD, + CustomFieldInstaller::USED_RATEPAY_SHOP_ID => $request['add_paydata[shop_id]'], + ] + )); + + $this->dataHandler->saveTransactionData($paymentTransaction, $salesChannelContext->getContext(), $data); + $this->dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); + $this->deviceFingerprintService->deleteDeviceIdentToken(); + } + + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + $definitions['ratepayIban'] = [new NotBlank(), new Iban()]; + $definitions['ratepayBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + + return $definitions; + } + + /** + * {@inheritdoc} + */ + public static function isCapturable(array $transactionData, array $customFields): bool + { + if (static::isNeverCapturable($transactionData, $customFields)) { + return false; + } + + return static::isTransactionAppointedAndCompleted($transactionData) || static::matchesIsCapturableDefaults($transactionData, $customFields); + } + + /** + * {@inheritdoc} + */ + public static function isRefundable(array $transactionData, array $customFields): bool + { + if (static::isNeverRefundable($transactionData, $customFields)) { + return false; + } + + return static::matchesIsRefundableDefaults($transactionData, $customFields); + } +} diff --git a/src/PaymentHandler/PayoneRatepayInstallmentPaymentHandler.php b/src/PaymentHandler/PayoneRatepayInstallmentPaymentHandler.php new file mode 100644 index 000000000..4403756c6 --- /dev/null +++ b/src/PaymentHandler/PayoneRatepayInstallmentPaymentHandler.php @@ -0,0 +1,169 @@ +client = $client; + $this->translator = $translator; + $this->dataHandler = $dataHandler; + $this->requestParameterFactory = $requestParameterFactory; + $this->deviceFingerprintService = $deviceFingerprintService; + } + + /** + * {@inheritdoc} + */ + public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $dataBag, SalesChannelContext $salesChannelContext): void + { + $requestData = $this->fetchRequestData(); + + // Get configured authorization method + $authorizationMethod = $this->getAuthorizationMethod( + $transaction->getOrder()->getSalesChannelId(), + 'ratepayInstallmentAuthorizationMethod', + 'preauthorization' + ); + + $paymentTransaction = PaymentTransaction::fromSyncPaymentTransactionStruct($transaction, $transaction->getOrder()); + + $request = $this->requestParameterFactory->getRequestParameter( + new PaymentTransactionStruct( + $paymentTransaction, + $requestData, + $salesChannelContext, + __CLASS__, + $authorizationMethod + ) + ); + + try { + $response = $this->client->request($request); + } catch (PayoneRequestException $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $exception->getResponse()['error']['CustomerMessage'] + ); + } catch (Throwable $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + if (empty($response['status']) || $response['status'] === 'ERROR') { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + // It differs depending on the authorization method + $clearingReference = $response['addpaydata']['clearing_reference'] ?? $response['clearing']['Reference']; + + // Prepare custom fields for the transaction + $data = $this->prepareTransactionCustomFields($request, $response, array_merge( + $this->getBaseCustomFields($response['status']), + [ + CustomFieldInstaller::WORK_ORDER_ID => $requestData->get('workorder'), + CustomFieldInstaller::CLEARING_REFERENCE => $clearingReference, + CustomFieldInstaller::CAPTURE_MODE => AbstractPayonePaymentHandler::PAYONE_STATE_COMPLETED, + CustomFieldInstaller::CLEARING_TYPE => AbstractPayonePaymentHandler::PAYONE_CLEARING_FNC, + CustomFieldInstaller::FINANCING_TYPE => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPS, + CustomFieldInstaller::USED_RATEPAY_SHOP_ID => $request['add_paydata[shop_id]'], + ] + )); + + $this->dataHandler->saveTransactionData($paymentTransaction, $salesChannelContext->getContext(), $data); + $this->dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); + $this->deviceFingerprintService->deleteDeviceIdentToken(); + } + + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + $definitions['ratepayBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + $definitions['ratepayIban'] = [new Iban()]; + + return $definitions; + } + + /** + * {@inheritdoc} + */ + public static function isCapturable(array $transactionData, array $customFields): bool + { + if (static::isNeverCapturable($transactionData, $customFields)) { + return false; + } + + return static::isTransactionAppointedAndCompleted($transactionData) || static::matchesIsCapturableDefaults($transactionData, $customFields); + } + + /** + * {@inheritdoc} + */ + public static function isRefundable(array $transactionData, array $customFields): bool + { + if (static::isNeverRefundable($transactionData, $customFields)) { + return false; + } + + return static::matchesIsRefundableDefaults($transactionData, $customFields); + } +} diff --git a/src/PaymentHandler/PayoneRatepayInvoicingPaymentHandler.php b/src/PaymentHandler/PayoneRatepayInvoicingPaymentHandler.php new file mode 100644 index 000000000..6072df273 --- /dev/null +++ b/src/PaymentHandler/PayoneRatepayInvoicingPaymentHandler.php @@ -0,0 +1,171 @@ +client = $client; + $this->translator = $translator; + $this->dataHandler = $dataHandler; + $this->requestParameterFactory = $requestParameterFactory; + $this->deviceFingerprintService = $deviceFingerprintService; + } + + /** + * {@inheritdoc} + */ + public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $dataBag, SalesChannelContext $salesChannelContext): void + { + $requestData = $this->fetchRequestData(); + + // Get configured authorization method + $authorizationMethod = $this->getAuthorizationMethod( + $transaction->getOrder()->getSalesChannelId(), + 'ratepayInvoicingAuthorizationMethod', + 'preauthorization' + ); + + $paymentTransaction = PaymentTransaction::fromSyncPaymentTransactionStruct($transaction, $transaction->getOrder()); + + $request = $this->requestParameterFactory->getRequestParameter( + new PaymentTransactionStruct( + $paymentTransaction, + $requestData, + $salesChannelContext, + __CLASS__, + $authorizationMethod + ) + ); + + try { + $response = $this->client->request($request); + } catch (PayoneRequestException $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $exception->getResponse()['error']['CustomerMessage'] + ); + } catch (Throwable $exception) { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + if (empty($response['status']) || $response['status'] === 'ERROR') { + $this->deviceFingerprintService->deleteDeviceIdentToken(); + throw new SyncPaymentProcessException( + $transaction->getOrderTransaction()->getId(), + $this->translator->trans('PayonePayment.errorMessages.genericError') + ); + } + + // It differs depending on the authorization method + $clearingReference = $response['addpaydata']['clearing_reference'] ?? $response['clearing']['Reference']; + + // Prepare custom fields for the transaction + $data = $this->prepareTransactionCustomFields($request, $response, array_merge( + $this->getBaseCustomFields($response['status']), + [ + CustomFieldInstaller::WORK_ORDER_ID => $requestData->get('workorder'), + CustomFieldInstaller::CLEARING_REFERENCE => $clearingReference, + CustomFieldInstaller::CAPTURE_MODE => AbstractPayonePaymentHandler::PAYONE_STATE_COMPLETED, + CustomFieldInstaller::CLEARING_TYPE => AbstractPayonePaymentHandler::PAYONE_CLEARING_FNC, + CustomFieldInstaller::FINANCING_TYPE => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPV, + CustomFieldInstaller::USED_RATEPAY_SHOP_ID => $request['add_paydata[shop_id]'], + ] + )); + + $this->dataHandler->saveTransactionData($paymentTransaction, $salesChannelContext->getContext(), $data); + $this->dataHandler->logResponse($paymentTransaction, $salesChannelContext->getContext(), ['request' => $request, 'response' => $response]); + $this->deviceFingerprintService->deleteDeviceIdentToken(); + } + + public function getValidationDefinitions(SalesChannelContext $salesChannelContext): array + { + $definitions = parent::getValidationDefinitions($salesChannelContext); + + $definitions['ratepayBirthday'] = [new NotBlank(), new Birthday(['value' => $this->getMinimumDate()])]; + + return $definitions; + } + + /** + * {@inheritdoc} + */ + public static function isCapturable(array $transactionData, array $customFields): bool + { + if (static::isNeverCapturable($transactionData, $customFields)) { + return false; + } + + if (!array_key_exists(CustomFieldInstaller::AUTHORIZATION_TYPE, $customFields)) { + return false; + } + + return static::isTransactionAppointedAndCompleted($transactionData) || static::matchesIsCapturableDefaults($transactionData, $customFields); + } + + /** + * {@inheritdoc} + */ + public static function isRefundable(array $transactionData, array $customFields): bool + { + if (static::isNeverRefundable($transactionData, $customFields)) { + return false; + } + + return static::matchesIsRefundableDefaults($transactionData, $customFields); + } +} diff --git a/src/PaymentMethod/PayoneRatepayDebit.php b/src/PaymentMethod/PayoneRatepayDebit.php new file mode 100644 index 000000000..1742eb133 --- /dev/null +++ b/src/PaymentMethod/PayoneRatepayDebit.php @@ -0,0 +1,43 @@ + [ + 'name' => 'PAYONE Ratepay Lastschrift', + 'description' => 'Zahle mit Ratepay Lastschrift', + ], + 'en-GB' => [ + 'name' => 'PAYONE Ratepay Direct Debit', + 'description' => 'Pay with Ratepay Direct Debit', + ], + ]; + + /** @var int */ + protected $position = 131; +} diff --git a/src/PaymentMethod/PayoneRatepayInstallment.php b/src/PaymentMethod/PayoneRatepayInstallment.php new file mode 100644 index 000000000..99fadcd44 --- /dev/null +++ b/src/PaymentMethod/PayoneRatepayInstallment.php @@ -0,0 +1,43 @@ + [ + 'name' => 'PAYONE Ratepay Ratenkauf', + 'description' => 'Zahle mit Ratepay Ratenkauf', + ], + 'en-GB' => [ + 'name' => 'PAYONE Ratepay Installments', + 'description' => 'Pay with Ratepay Installments', + ], + ]; + + /** @var int */ + protected $position = 132; +} diff --git a/src/PaymentMethod/PayoneRatepayInvoicing.php b/src/PaymentMethod/PayoneRatepayInvoicing.php new file mode 100644 index 000000000..5b9bab16d --- /dev/null +++ b/src/PaymentMethod/PayoneRatepayInvoicing.php @@ -0,0 +1,43 @@ + [ + 'name' => 'PAYONE Ratepay Rechnungskauf', + 'description' => 'Zahle mit dem Ratepay Rechnungskauf', + ], + 'en-GB' => [ + 'name' => 'PAYONE Ratepay Open Invoice', + 'description' => 'Pay with Ratepay Open Invoice', + ], + ]; + + /** @var int */ + protected $position = 130; +} diff --git a/src/Payone/RequestParameter/Builder/AbstractRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/AbstractRequestParameterBuilder.php index 86f1c8a9a..427da88f7 100644 --- a/src/Payone/RequestParameter/Builder/AbstractRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/AbstractRequestParameterBuilder.php @@ -27,6 +27,8 @@ abstract class AbstractRequestParameterBuilder public const REQUEST_ACTION_GET_FILE = 'getfile'; public const REQUEST_ACTION_MANAGE_MANDATE = 'managemandate'; public const REQUEST_ACTION_DEBIT = 'debit'; + public const REQUEST_ACTION_RATEPAY_PROFILE = 'ratepayProfile'; + public const REQUEST_ACTION_RATEPAY_CALCULATION = 'ratepayCalculation'; public const CLEARING_TYPE_DEBIT = 'elv'; public const CLEARING_TYPE_WALLET = 'wlt'; diff --git a/src/Payone/RequestParameter/Builder/Capture/CaptureRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/Capture/CaptureRequestParameterBuilder.php index 9176995d8..457ae0fa7 100644 --- a/src/Payone/RequestParameter/Builder/Capture/CaptureRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/Capture/CaptureRequestParameterBuilder.php @@ -6,6 +6,7 @@ use PayonePayment\Components\Currency\CurrencyPrecisionInterface; use PayonePayment\Installer\CustomFieldInstaller; +use PayonePayment\PaymentHandler\PaymentHandlerGroups; use PayonePayment\PaymentHandler\PayoneBancontactPaymentHandler; use PayonePayment\PaymentHandler\PayoneSofortBankingPaymentHandler; use PayonePayment\PaymentHandler\PayoneTrustlyPaymentHandler; @@ -17,11 +18,11 @@ class CaptureRequestParameterBuilder extends AbstractRequestParameterBuilder { - private const CAPTUREMODE_COMPLETED = 'completed'; - private const CAPTUREMODE_INCOMPLETE = 'notcompleted'; - private const SETTLEACCOUNT_YES = 'yes'; - private const SETTLEACCOUNT_AUTO = 'auto'; - private const SETTLEACCOUNT_NO = 'no'; + public const CAPTUREMODE_COMPLETED = 'completed'; + public const CAPTUREMODE_INCOMPLETE = 'notcompleted'; + public const SETTLEACCOUNT_YES = 'yes'; + public const SETTLEACCOUNT_AUTO = 'auto'; + public const SETTLEACCOUNT_NO = 'no'; /** @var CurrencyPrecisionInterface */ private $currencyPrecision; @@ -83,6 +84,11 @@ public function getRequestParameter(AbstractRequestParameterStruct $arguments): $parameters['settleaccount'] = $isCompleted ? self::SETTLEACCOUNT_YES : self::SETTLEACCOUNT_NO; } + if (in_array($arguments->getPaymentMethod(), PaymentHandlerGroups::RATEPAY)) { + $parameters['settleaccount'] = 'yes'; + $parameters['add_paydata[shop_id]'] = $customFields[CustomFieldInstaller::USED_RATEPAY_SHOP_ID]; + } + return $parameters; } diff --git a/src/Payone/RequestParameter/Builder/CustomerRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/CustomerRequestParameterBuilder.php index 5998af08c..0295e92fe 100644 --- a/src/Payone/RequestParameter/Builder/CustomerRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/CustomerRequestParameterBuilder.php @@ -17,6 +17,9 @@ use PayonePayment\PaymentHandler\PayonePaypalExpressPaymentHandler; use PayonePayment\PaymentHandler\PayonePaypalPaymentHandler; use PayonePayment\PaymentHandler\PayonePrepaymentPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayDebitPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayInstallmentPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayInvoicingPaymentHandler; use PayonePayment\PaymentHandler\PayoneSecureInvoicePaymentHandler; use PayonePayment\PaymentHandler\PayoneSofortBankingPaymentHandler; use PayonePayment\PaymentHandler\PayoneTrustlyPaymentHandler; @@ -140,6 +143,9 @@ public function supports(AbstractRequestParameterStruct $arguments): bool case PayoneSecureInvoicePaymentHandler::class: case PayoneOpenInvoicePaymentHandler::class: case PayonePrepaymentPaymentHandler::class: + case PayoneRatepayDebitPaymentHandler::class: + case PayoneRatepayInstallmentPaymentHandler::class: + case PayoneRatepayInvoicingPaymentHandler::class: return true; } diff --git a/src/Payone/RequestParameter/Builder/OrderLinesRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/OrderLinesRequestParameterBuilder.php index 172295e44..49b49f067 100644 --- a/src/Payone/RequestParameter/Builder/OrderLinesRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/OrderLinesRequestParameterBuilder.php @@ -10,6 +10,9 @@ use PayonePayment\PaymentHandler\PayonePayolutionDebitPaymentHandler; use PayonePayment\PaymentHandler\PayonePayolutionInstallmentPaymentHandler; use PayonePayment\PaymentHandler\PayonePayolutionInvoicingPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayDebitPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayInstallmentPaymentHandler; +use PayonePayment\PaymentHandler\PayoneRatepayInvoicingPaymentHandler; use PayonePayment\PaymentHandler\PayoneSecureInvoicePaymentHandler; use PayonePayment\Payone\RequestParameter\Struct\AbstractRequestParameterStruct; use PayonePayment\Payone\RequestParameter\Struct\FinancialTransactionStruct; @@ -61,6 +64,9 @@ public function supports(AbstractRequestParameterStruct $arguments): bool case PayoneSecureInvoicePaymentHandler::class: case PayoneOpenInvoicePaymentHandler::class: case PayoneBancontactPaymentHandler::class: + case PayoneRatepayDebitPaymentHandler::class: + case PayoneRatepayInstallmentPaymentHandler::class: + case PayoneRatepayInvoicingPaymentHandler::class: return true; } diff --git a/src/Payone/RequestParameter/Builder/RatepayDebit/AuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayDebit/AuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..9b34f5309 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayDebit/AuthorizeRequestParameterBuilder.php @@ -0,0 +1,169 @@ +orderFetcher = $orderFetcher; + $this->profileService = $profileService; + $this->deviceFingerprintService = $deviceFingerprintService; + $this->customerRepository = $customerRepository; + $this->lineItemHydrator = $lineItemHydrator; + } + + /** @param PaymentTransactionStruct $arguments */ + public function getRequestParameter(AbstractRequestParameterStruct $arguments): array + { + $dataBag = $arguments->getRequestData(); + $salesChannelContext = $arguments->getSalesChannelContext(); + $context = $salesChannelContext->getContext(); + $paymentTransaction = $arguments->getPaymentTransaction(); + $order = $this->getOrder($paymentTransaction->getOrder()->getId(), $context); + $currency = $this->getOrderCurrency($order, $context); + $profile = $this->getProfile($order, PayoneRatepayDebitPaymentHandler::class); + + $parameters = [ + 'request' => self::REQUEST_ACTION_AUTHORIZE, + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPD, + 'iban' => $dataBag->get('ratepayIban'), + 'add_paydata[customer_allow_credit_inquiry]' => 'yes', + 'add_paydata[shop_id]' => $profile->getShopId(), + 'add_paydata[device_token]' => $this->deviceFingerprintService->getDeviceIdentToken(), + ]; + + $this->applyPhoneParameter($order, $parameters, $dataBag, $context); + $this->applyBirthdayParameter($parameters, $dataBag); + + if ($order->getLineItems() !== null) { + $parameters = array_merge($parameters, $this->lineItemHydrator->mapOrderLines($currency, $order, $context)); + } + + return $parameters; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayDebitPaymentHandler::class && $action === self::REQUEST_ACTION_AUTHORIZE; + } + + protected function getOrder(string $orderId, Context $context): OrderEntity + { + // Load order to make sure all associations are set + $order = $this->orderFetcher->getOrderById($orderId, $context); + + if (null === $order) { + throw new RuntimeException('missing order'); + } + + return $order; + } + + protected function getProfile(OrderEntity $order, string $paymentHandler): Profile + { + $profile = $this->profileService->getProfileByOrder($order, $paymentHandler); + + if ($profile === null) { + throw new RuntimeException('no ratepay profile found'); + } + + return $profile; + } + + protected function applyPhoneParameter(OrderEntity $order, array &$parameters, ParameterBag $dataBag, Context $context): void + { + if (!$order->getOrderCustomer()) { + throw new RuntimeException('missing order customer'); + } + + $customer = $order->getOrderCustomer()->getCustomer(); + + if (!$customer) { + throw new RuntimeException('missing customer'); + } + + $customerCustomFields = $customer->getCustomFields() ?? []; + $customFieldPhoneNumber = $customerCustomFields[CustomFieldInstaller::CUSTOMER_PHONE_NUMBER] ?? null; + $submittedPhoneNumber = $dataBag->get('ratepayPhone'); + + if (!empty($submittedPhoneNumber) && $submittedPhoneNumber !== $customFieldPhoneNumber) { + // Update the phone number that is stored at the customer + $customFieldPhoneNumber = $submittedPhoneNumber; + $customerCustomFields[CustomFieldInstaller::CUSTOMER_PHONE_NUMBER] = $customFieldPhoneNumber; + $this->customerRepository->update( + [ + [ + 'id' => $customer->getId(), + 'customFields' => $customerCustomFields, + ], + ], + $context + ); + } + + if (!$customFieldPhoneNumber) { + throw new RuntimeException('missing phone number'); + } + + $parameters['telephonenumber'] = $customerCustomFields[CustomFieldInstaller::CUSTOMER_PHONE_NUMBER]; + } + + protected function applyBirthdayParameter(array &$parameters, ParameterBag $dataBag): void + { + if (!empty($dataBag->get('ratepayBirthday'))) { + $birthday = \DateTime::createFromFormat('Y-m-d', $dataBag->get('ratepayBirthday')); + + if (!empty($birthday)) { + $parameters['birthday'] = $birthday->format('Ymd'); + } + } + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayDebit/PreAuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayDebit/PreAuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..c0a274f96 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayDebit/PreAuthorizeRequestParameterBuilder.php @@ -0,0 +1,32 @@ + self::REQUEST_ACTION_PREAUTHORIZE, + ]); + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayDebitPaymentHandler::class && $action === self::REQUEST_ACTION_PREAUTHORIZE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayDebit/ProfileRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayDebit/ProfileRequestParameterBuilder.php new file mode 100644 index 000000000..aa292a2c4 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayDebit/ProfileRequestParameterBuilder.php @@ -0,0 +1,39 @@ + self::REQUEST_ACTION_GENERIC_PAYMENT, + 'add_paydata[action]' => 'profile', + 'add_paydata[shop_id]' => $arguments->getShopId(), + 'currency' => $arguments->getCurrency(), + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPD, + ]; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof RatepayProfileStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayDebitPaymentHandler::class && $action === self::REQUEST_ACTION_RATEPAY_PROFILE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInstallment/AuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInstallment/AuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..c9b577662 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInstallment/AuthorizeRequestParameterBuilder.php @@ -0,0 +1,95 @@ +currencyPrecision = $currencyPrecision; + } + + /** @param PaymentTransactionStruct $arguments */ + public function getRequestParameter(AbstractRequestParameterStruct $arguments): array + { + $dataBag = $arguments->getRequestData(); + $salesChannelContext = $arguments->getSalesChannelContext(); + $context = $salesChannelContext->getContext(); + $paymentTransaction = $arguments->getPaymentTransaction(); + $order = $this->getOrder($paymentTransaction->getOrder()->getId(), $context); + $currency = $this->getOrderCurrency($order, $context); + $profile = $this->getProfile($order, PayoneRatepayInstallmentPaymentHandler::class); + + $parameters = [ + 'request' => self::REQUEST_ACTION_AUTHORIZE, + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPS, + 'add_paydata[customer_allow_credit_inquiry]' => 'yes', + 'add_paydata[installment_amount]' => $this->currencyPrecision->getRoundedTotalAmount((float) $dataBag->get('ratepayInstallmentAmount'), $currency), + 'add_paydata[installment_number]' => (int) $dataBag->get('ratepayInstallmentNumber'), + 'add_paydata[last_installment_amount]' => $this->currencyPrecision->getRoundedTotalAmount((float) $dataBag->get('ratepayLastInstallmentAmount'), $currency), + 'add_paydata[interest_rate]' => $this->currencyPrecision->getRoundedTotalAmount((float) $dataBag->get('ratepayInterestRate'), $currency), + 'add_paydata[amount]' => $this->currencyPrecision->getRoundedTotalAmount((float) $dataBag->get('ratepayTotalAmount'), $currency), + 'add_paydata[shop_id]' => $profile->getShopId(), + 'add_paydata[device_token]' => $this->deviceFingerprintService->getDeviceIdentToken(), + ]; + + if ($dataBag->get('ratepayIban')) { + $parameters['iban'] = $dataBag->get('ratepayIban'); + $parameters['add_paydata[debit_paytype]'] = 'DIRECT-DEBIT'; + } else { + $parameters['add_paydata[debit_paytype]'] = 'BANK-TRANSFER'; + } + + $this->applyPhoneParameter($order, $parameters, $dataBag, $context); + $this->applyBirthdayParameter($parameters, $dataBag); + + if ($order->getLineItems() !== null) { + $parameters = array_merge($parameters, $this->lineItemHydrator->mapOrderLines($currency, $order, $context)); + } + + return $parameters; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInstallmentPaymentHandler::class && $action === self::REQUEST_ACTION_AUTHORIZE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInstallment/CalculationRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInstallment/CalculationRequestParameterBuilder.php new file mode 100644 index 000000000..290002a3f --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInstallment/CalculationRequestParameterBuilder.php @@ -0,0 +1,66 @@ +getRequestData(); + $currency = $this->getOrderCurrency(null, $arguments->getSalesChannelContext()->getContext()); + $cart = $arguments->getCart(); + $profile = $arguments->getProfile(); + $installmentType = $dataBag->get('ratepayInstallmentType'); + + $parameters = [ + 'request' => self::REQUEST_ACTION_GENERIC_PAYMENT, + 'add_paydata[action]' => 'calculation', + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPS, + 'amount' => $this->currencyPrecision->getRoundedTotalAmount($cart->getPrice()->getTotalPrice(), $currency), + 'currency' => $currency->getIsoCode(), + 'add_paydata[shop_id]' => $profile->getShopId(), + 'add_paydata[customer_allow_credit_inquiry]' => 'yes', + ]; + + if ($installmentType === self::INSTALLMENT_TYPE_RATE) { + $parameters['add_paydata[calculation_type]'] = 'calculation-by-rate'; + $parameters['add_paydata[rate]'] = $this->currencyPrecision->getRoundedTotalAmount( + (float) $dataBag->get('ratepayInstallmentValue'), + $currency + ); + } elseif ($installmentType === self::INSTALLMENT_TYPE_TIME) { + $parameters['add_paydata[calculation_type]'] = 'calculation-by-time'; + $parameters['add_paydata[month]'] = $dataBag->get('ratepayInstallmentValue'); + } else { + throw new RuntimeException('invalid installment type'); + } + + return $parameters; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof RatepayCalculationStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInstallmentPaymentHandler::class && $action === self::REQUEST_ACTION_RATEPAY_CALCULATION; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInstallment/PreAuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInstallment/PreAuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..363188270 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInstallment/PreAuthorizeRequestParameterBuilder.php @@ -0,0 +1,32 @@ + self::REQUEST_ACTION_PREAUTHORIZE, + ]); + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInstallmentPaymentHandler::class && $action === self::REQUEST_ACTION_PREAUTHORIZE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInstallment/ProfileRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInstallment/ProfileRequestParameterBuilder.php new file mode 100644 index 000000000..7e6a61302 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInstallment/ProfileRequestParameterBuilder.php @@ -0,0 +1,39 @@ + self::REQUEST_ACTION_GENERIC_PAYMENT, + 'add_paydata[action]' => 'profile', + 'add_paydata[shop_id]' => $arguments->getShopId(), + 'currency' => $arguments->getCurrency(), + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPS, + ]; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof RatepayProfileStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInstallmentPaymentHandler::class && $action === self::REQUEST_ACTION_RATEPAY_PROFILE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInvoicing/AuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInvoicing/AuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..deeee4d96 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInvoicing/AuthorizeRequestParameterBuilder.php @@ -0,0 +1,56 @@ +getRequestData(); + $salesChannelContext = $arguments->getSalesChannelContext(); + $context = $salesChannelContext->getContext(); + $paymentTransaction = $arguments->getPaymentTransaction(); + $order = $this->getOrder($paymentTransaction->getOrder()->getId(), $context); + $currency = $this->getOrderCurrency($order, $context); + $profile = $this->getProfile($order, PayoneRatepayInvoicingPaymentHandler::class); + + $parameters = [ + 'request' => self::REQUEST_ACTION_AUTHORIZE, + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPV, + 'add_paydata[customer_allow_credit_inquiry]' => 'yes', + 'add_paydata[shop_id]' => $profile->getShopId(), + 'add_paydata[device_token]' => $this->deviceFingerprintService->getDeviceIdentToken(), + ]; + + $this->applyPhoneParameter($order, $parameters, $dataBag, $context); + $this->applyBirthdayParameter($parameters, $dataBag); + + if ($order->getLineItems() !== null) { + $parameters = array_merge($parameters, $this->lineItemHydrator->mapOrderLines($currency, $order, $context)); + } + + return $parameters; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInvoicingPaymentHandler::class && $action === self::REQUEST_ACTION_AUTHORIZE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInvoicing/PreAuthorizeRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInvoicing/PreAuthorizeRequestParameterBuilder.php new file mode 100644 index 000000000..0a803c35f --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInvoicing/PreAuthorizeRequestParameterBuilder.php @@ -0,0 +1,32 @@ + self::REQUEST_ACTION_PREAUTHORIZE, + ]); + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof PaymentTransactionStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInvoicingPaymentHandler::class && $action === self::REQUEST_ACTION_PREAUTHORIZE; + } +} diff --git a/src/Payone/RequestParameter/Builder/RatepayInvoicing/ProfileRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/RatepayInvoicing/ProfileRequestParameterBuilder.php new file mode 100644 index 000000000..cb6c3ff63 --- /dev/null +++ b/src/Payone/RequestParameter/Builder/RatepayInvoicing/ProfileRequestParameterBuilder.php @@ -0,0 +1,39 @@ + self::REQUEST_ACTION_GENERIC_PAYMENT, + 'add_paydata[action]' => 'profile', + 'add_paydata[shop_id]' => $arguments->getShopId(), + 'currency' => $arguments->getCurrency(), + 'clearingtype' => self::CLEARING_TYPE_FINANCING, + 'financingtype' => AbstractPayonePaymentHandler::PAYONE_FINANCING_RPV, + ]; + } + + public function supports(AbstractRequestParameterStruct $arguments): bool + { + if (!($arguments instanceof RatepayProfileStruct)) { + return false; + } + + $paymentMethod = $arguments->getPaymentMethod(); + $action = $arguments->getAction(); + + return $paymentMethod === PayoneRatepayInvoicingPaymentHandler::class && $action === self::REQUEST_ACTION_RATEPAY_PROFILE; + } +} diff --git a/src/Payone/RequestParameter/Builder/Refund/RefundRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/Refund/RefundRequestParameterBuilder.php index db26c820d..efddf92ad 100644 --- a/src/Payone/RequestParameter/Builder/Refund/RefundRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/Refund/RefundRequestParameterBuilder.php @@ -6,6 +6,7 @@ use PayonePayment\Components\Currency\CurrencyPrecisionInterface; use PayonePayment\Installer\CustomFieldInstaller; +use PayonePayment\PaymentHandler\PaymentHandlerGroups; use PayonePayment\PaymentHandler\PayoneDebitPaymentHandler; use PayonePayment\Payone\RequestParameter\Builder\AbstractRequestParameterBuilder; use PayonePayment\Payone\RequestParameter\Struct\AbstractRequestParameterStruct; @@ -64,6 +65,11 @@ public function getRequestParameter(AbstractRequestParameterStruct $arguments): $parameters['iban'] = $firstTransaction['request']['iban']; } + if (in_array($arguments->getPaymentMethod(), PaymentHandlerGroups::RATEPAY)) { + $parameters['settleaccount'] = 'yes'; + $parameters['add_paydata[shop_id]'] = $customFields[CustomFieldInstaller::USED_RATEPAY_SHOP_ID]; + } + return $parameters; } diff --git a/src/Payone/RequestParameter/Builder/SystemRequestParameterBuilder.php b/src/Payone/RequestParameter/Builder/SystemRequestParameterBuilder.php index 5554d6c2c..4aa5bade0 100644 --- a/src/Payone/RequestParameter/Builder/SystemRequestParameterBuilder.php +++ b/src/Payone/RequestParameter/Builder/SystemRequestParameterBuilder.php @@ -16,6 +16,7 @@ use PayonePayment\Payone\RequestParameter\Struct\PayolutionAdditionalActionStruct; use PayonePayment\Payone\RequestParameter\Struct\TestCredentialsStruct; use PayonePayment\PayonePayment; +use RuntimeException; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Plugin\PluginService; @@ -76,34 +77,36 @@ public function getRequestParameter(AbstractRequestParameterStruct $arguments): public function supports(AbstractRequestParameterStruct $arguments): bool { - if ($arguments instanceof TestCredentialsStruct) { - return false; - } - - return true; + return !($arguments instanceof TestCredentialsStruct); } - /** - * @param CheckoutDetailsStruct|CreditCardCheckStruct|FinancialTransactionStruct|GetFileStruct|PaymentTransactionStruct|PayolutionAdditionalActionStruct $arguments - */ private function getContext(AbstractRequestParameterStruct $arguments): Context { if ($arguments instanceof FinancialTransactionStruct) { return $arguments->getContext(); } - return $arguments->getSalesChannelContext()->getContext(); + if (method_exists($arguments, 'getSalesChannelContext')) { + return $arguments->getSalesChannelContext()->getContext(); + } + + return Context::createDefaultContext(); } - /** - * @param CheckoutDetailsStruct|CreditCardCheckStruct|FinancialTransactionStruct|GetFileStruct|PaymentTransactionStruct|PayolutionAdditionalActionStruct $arguments - */ private function getSalesChannelId(AbstractRequestParameterStruct $arguments): string { if ($arguments instanceof FinancialTransactionStruct) { return $arguments->getPaymentTransaction()->getOrder()->getSalesChannelId(); } - return $arguments->getSalesChannelContext()->getSalesChannel()->getId(); + if (method_exists($arguments, 'getSalesChannelContext')) { + return $arguments->getSalesChannelContext()->getSalesChannel()->getId(); + } + + if (method_exists($arguments, 'getSalesChannelId')) { + return $arguments->getSalesChannelId(); + } + + throw new RuntimeException('missing sales channel id'); } } diff --git a/src/Payone/RequestParameter/RequestParameterFactory.php b/src/Payone/RequestParameter/RequestParameterFactory.php index 6ba937579..1e3fa6dd8 100644 --- a/src/Payone/RequestParameter/RequestParameterFactory.php +++ b/src/Payone/RequestParameter/RequestParameterFactory.php @@ -30,17 +30,16 @@ public function __construct(iterable $requestParameterBuilder) public function getRequestParameter(AbstractRequestParameterStruct $arguments): array { - $parameters = []; + $collectedParameters = []; foreach ($this->requestParameterBuilder as $builder) { if ($builder->supports($arguments) === true) { - $parameters = array_merge( - $parameters, - $builder->getRequestParameter($arguments) - ); + $collectedParameters[] = $builder->getRequestParameter($arguments); } } + $parameters = array_merge(...$collectedParameters); + if (empty($parameters)) { throw new RuntimeException('No valid request parameter builder found'); } diff --git a/src/Payone/RequestParameter/Struct/RatepayCalculationStruct.php b/src/Payone/RequestParameter/Struct/RatepayCalculationStruct.php new file mode 100644 index 000000000..9eb4900f2 --- /dev/null +++ b/src/Payone/RequestParameter/Struct/RatepayCalculationStruct.php @@ -0,0 +1,44 @@ +cart = $cart; + $this->requestData = $requestData; + $this->salesChannelContext = $salesChannelContext; + $this->profile = $profile; + $this->paymentMethod = $paymentMethod; + $this->action = $action; + } + + public function getProfile(): Profile + { + return $this->profile; + } +} diff --git a/src/Payone/RequestParameter/Struct/RatepayProfileStruct.php b/src/Payone/RequestParameter/Struct/RatepayProfileStruct.php new file mode 100644 index 000000000..2d7d8dc65 --- /dev/null +++ b/src/Payone/RequestParameter/Struct/RatepayProfileStruct.php @@ -0,0 +1,46 @@ +shopId = $shopId; + $this->currency = $currency; + $this->salesChannelId = $salesChannelId; + $this->paymentMethod = $paymentMethod; + $this->action = $action; + } + + public function getShopId(): int + { + return $this->shopId; + } + + public function getCurrency(): string + { + return $this->currency; + } + + public function getSalesChannelId(): string + { + return $this->salesChannelId; + } +} diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/index.js b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/index.js new file mode 100644 index 000000000..6ccba551c --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/index.js @@ -0,0 +1,98 @@ +import './payone-ratepay-profile-configurations.scss'; +import template from './payone-ratepay-profile-configurations.html.twig'; + +const {Component} = Shopware; + +Component.register('payone-ratepay-profile-configurations', { + template, + + inject: ['PayonePaymentSettingsService'], + + props: { + value: { + type: Object, + required: false, + default() { + return {}; + } + }, + name: { + type: String, + required: true + }, + }, + + data() { + return { + isLoading: false, + configuration: this.value + } + }, + + created() { + this.createdComponent(); + }, + + destroyed() { + this.destroyedComponent(); + }, + + computed: { + profileConfigurations() { + const name = this.name; + let profileConfigurations = []; + + for (const shopId in this.configuration) { + let minBasket = ''; + let maxBasket = ''; + + switch (name) { + case 'PayonePayment.settings.ratepayDebitProfileConfigurations': + minBasket = this.configuration[shopId]['tx-limit-elv-min']; + maxBasket = this.configuration[shopId]['tx-limit-elv-max']; + break; + case 'PayonePayment.settings.ratepayInstallmentProfileConfigurations': + minBasket = this.configuration[shopId]['tx-limit-installment-min']; + maxBasket = this.configuration[shopId]['tx-limit-installment-max']; + break; + case 'PayonePayment.settings.ratepayInvoicingProfileConfigurations': + minBasket = this.configuration[shopId]['tx-limit-invoice-min']; + maxBasket = this.configuration[shopId]['tx-limit-invoice-max']; + break; + default: + return; + } + + const profileConfig = { + 'shopId': shopId, + 'shopCurrency': this.configuration[shopId]['currency'], + 'invoiceCountry': this.configuration[shopId]['country-code-billing'], + 'shippingCountry': this.configuration[shopId]['country-code-delivery'], + 'minBasket': minBasket, + 'maxBasket': maxBasket + } + + profileConfigurations.push(profileConfig); + } + + return profileConfigurations; + } + }, + + methods: { + createdComponent() { + this.$root.$on('payone-ratepay-profiles-update-result', this.onProfilesUpdateResult); + console.log(this.configuration); + }, + + destroyedComponent() { + this.$root.$off('payone-ratepay-profiles-update-result'); + }, + + onProfilesUpdateResult(result) { + if (result['updates'][this.name]) { + this.configuration = result['updates'][this.name]; + } + } + } +}); diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.html.twig b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.html.twig new file mode 100644 index 000000000..206427526 --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.html.twig @@ -0,0 +1,28 @@ +{% block payone_ratepay_profile_configurations %} +
+

{{ $tc('payone-payment.general.headlines.ratepayProfileConfigurations') }}

+ + +
+{% endblock %} diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.scss b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.scss new file mode 100644 index 000000000..3ccde2b3c --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profile-configurations/payone-ratepay-profile-configurations.scss @@ -0,0 +1,18 @@ +.payone-ratepay-profile-configurations { + margin-top: 20px; + + @media screen and (min-width: 768px) { + width: 50%; + } + + .payone-ratepay-profile-configuration--headline { + font-weight: 600; + margin-top: 20px; + } + + .sw-description-list { + dt { + text-align: right; + } + } +} diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profiles/index.js b/src/Resources/app/administration/src/component/payone-ratepay-profiles/index.js new file mode 100644 index 000000000..5b81b4b9e --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profiles/index.js @@ -0,0 +1,172 @@ +import './payone-ratepay-profiles.scss'; +import template from './payone-ratepay-profiles.html.twig'; + +const { Component, Utils } = Shopware; + +Component.register('payone-ratepay-profiles', { + template, + + props: { + value: { + type: Array, + required: false, + default() { + return []; + } + }, + name: { + type: String, + required: true + }, + }, + + data() { + return { + selectedItems: {}, + newItem: null, + showDuplicateAlert: false, + showEmptyAlert: false, + profiles: this.value, + }; + }, + + computed: { + getLineItemColumns() { + return [{ + property: 'shopId', + dataIndex: 'shopId', + label: this.$tc('payone-payment.general.label.shopId'), + allowResize: false, + inlineEdit: 'string', + width: '200px', + primary: true, + }, { + property: 'currency', + dataIndex: 'currency', + label: this.$tc('payone-payment.general.label.currency'), + allowResize: false, + inlineEdit: 'string', + width: '200px', + primary: true, + }, { + property: 'error', + label: this.$tc('payone-payment.general.label.error'), + allowResize: false, + width: '100px', + primary: true, + }]; + } + }, + + watch: { + profiles(profiles) { + this.$emit('input', profiles); + this.$emit('change', profiles); + }, + }, + + created() { + this.createdComponent(); + }, + + destroyed() { + this.destroyedComponent(); + }, + + methods: { + createdComponent() { + this.$root.$on('payone-ratepay-profiles-update-result', this.onProfilesUpdateResult); + }, + + destroyedComponent() { + this.$root.$off('payone-ratepay-profiles-update-result'); + }, + + onProfilesUpdateResult(result) { + if (result['updates'][this.name]) { + this.profiles = result['updates'][this.name]; + } + if (result['errors'][this.name]) { + for (const error of result['errors'][this.name]) { + this.profiles.push(error); + } + } + }, + + onInlineEditCancel(currentItem) { + if(currentItem.shopId === "" && currentItem.currency === "") { + this.profiles.forEach(function(item, index, array) { + if(item.id === currentItem.id) { + array.splice(index, 1); + } + }); + } + + this.$emit('item-cancel'); + }, + + onInlineEditSave(currentItem) { + if(currentItem.shopId !== "" && currentItem.currency !== "") { + this.showEmptyAlert = false; + let shopIdExists = false; + this.profiles.forEach(function(item) { + if(item.id !== currentItem.id && item.shopId === currentItem.shopId) { + shopIdExists = true; + } + }); + + if(shopIdExists) { + this.showDuplicateAlert = true; + + this.$nextTick(() => { + this.$refs.shopIdsDataGrid.currentInlineEditId = currentItem.id; + this.$refs.shopIdsDataGrid.enableInlineEdit(); + }); + } else { + this.showDuplicateAlert = false; + } + } else { + this.showEmptyAlert = true; + + this.$nextTick(() => { + this.$refs.shopIdsDataGrid.currentInlineEditId = currentItem.id; + this.$refs.shopIdsDataGrid.enableInlineEdit(); + }); + } + + this.$emit('update-list', this.profiles); + }, + + createNewLineItem() { + let emptyProfilesList = false; + + emptyProfilesList = this.profiles.length === 0; + + if(emptyProfilesList) { + this.createLine(); + return; + } + + if(this.profiles[this.profiles.length - 1].shopId !== "") { + this.createLine(); + } + }, + + createLine() { + const newId = Utils.createId(); + + this.profiles.push({'id': newId, 'shopId': '', 'currency': '' }); + + this.$nextTick(() => { + this.$refs.shopIdsDataGrid.currentInlineEditId = newId; + this.$refs.shopIdsDataGrid.enableInlineEdit(); + }); + }, + + onDeleteSelectedItem(itemToDelete) { + this.profiles = this.profiles.filter(currentItem => currentItem.shopId !== itemToDelete.shopId); + + this.$emit('deleted', this.profiles); + }, + } +}); diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.html.twig b/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.html.twig new file mode 100644 index 000000000..82d21bb6a --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.html.twig @@ -0,0 +1,79 @@ +{% block payone_ratepay_profiles %} +
+ {% block payone_ratepay_shop_ids %} +

{{ $tc('payone-payment.general.headlines.ratepayProfiles') }}

+ + + {% block payone_ratepay_shop_ids_actions %} + + + {% block payone_ratepay_shop_ids_create_actions %} +
+ + {{ $tc('payone-payment.general.actions.addShop') }} + +
+ {% endblock %} +
+ {% endblock %} + + {% block payone_ratepay_shop_ids_grid %} + + {% block payone_ratepay_shop_ids_grid_columns %} + {% block payone_ratepay_shop_ids_grid_column_status %} + + {% endblock %} + + {% block payone_ratepay_shop_ids_bulk_actions %} + + {% endblock %} + {% endblock %} + + {% endblock %} + + {% block payone_ratepay_shop_ids_error %} + + {{ $tc('payone-payment.general.errors.existingShopId') }} + + + + {{ $tc('payone-payment.general.errors.emptyInputs') }} + + {% endblock %} +
+ {% endblock %} +
+{% endblock %} diff --git a/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.scss b/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.scss new file mode 100644 index 000000000..1fbf68862 --- /dev/null +++ b/src/Resources/app/administration/src/component/payone-ratepay-profiles/payone-ratepay-profiles.scss @@ -0,0 +1,6 @@ +.payone-ratepay-profiles { + .sw-alert { + margin: 20px auto; + width: 100%; + } +} diff --git a/src/Resources/app/administration/src/main.js b/src/Resources/app/administration/src/main.js index f3731c6e7..1d75607ef 100644 --- a/src/Resources/app/administration/src/main.js +++ b/src/Resources/app/administration/src/main.js @@ -1,3 +1,5 @@ +import './component/payone-ratepay-profile-configurations'; +import './component/payone-ratepay-profiles'; import './module/payone-payment'; import './module/payone-notification-target'; import './api/payone-payment.service'; diff --git a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/index.js b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/index.js index e04d812ff..5f4282455 100644 --- a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/index.js +++ b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/index.js @@ -14,7 +14,7 @@ Component.register('payone-settings', { inject: [ 'PayonePaymentSettingsService' ], - data() { + data() { return { isLoading: false, isTesting: false, @@ -49,6 +49,9 @@ Component.register('payone-settings', { 'payment_open_invoice': true, 'payment_apple_pay': true, 'payment_bancontact': true, + 'payment_ratepay_debit': true, + 'payment_ratepay_installment': true, + 'payment_ratepay_invoicing': true, }, }; }, @@ -115,6 +118,9 @@ Component.register('payone-settings', { 'openInvoice', 'applePay', 'bancontact', + 'ratepayDebit', + 'ratepayInstallment', + 'ratepayInvoicing', ]; }, @@ -195,7 +201,9 @@ Component.register('payone-settings', { this.isSaveSuccessful = false; this.isLoading = true; - this.$refs.systemConfig.saveAll().then(() => { + this.$refs.systemConfig.saveAll().then((response) => { + this.handleRatepayProfileUpdates(response); + this.isLoading = false; this.isSaveSuccessful = true; }).catch(() => { @@ -329,5 +337,25 @@ Component.register('payone-settings', { return bind; }, + + handleRatepayProfileUpdates(response) { + const salesChannelId = this.$refs.systemConfig.currentSalesChannelId; + + if (response.payoneRatepayProfilesUpdateResult && response.payoneRatepayProfilesUpdateResult[salesChannelId]) { + const resultBySalesChannel = response.payoneRatepayProfilesUpdateResult[salesChannelId]; + + this.$root.$emit( + 'payone-ratepay-profiles-update-result', + resultBySalesChannel + ); + + if (!Array.isArray(resultBySalesChannel.errors)) { + this.createNotificationError({ + title: this.$tc('payone-payment.settingsForm.titleError'), + message: this.$tc('payone-payment.settingsForm.messageSaveError.ratepayProfilesUpdateFailed') + }); + } + } + } } }); diff --git a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/payone-settings.html.twig b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/payone-settings.html.twig index 6974d2664..720a047f6 100644 --- a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/payone-settings.html.twig +++ b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/payone-settings.html.twig @@ -180,6 +180,13 @@ v-bind="getElementBind(getBind(element, config))" v-model="config[element.name]" /> + +
+ +

{{ $tc('payone-payment.general.label.reloadConfigInfo') }}

+
+ diff --git a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/style.scss b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/style.scss index b44d3eac0..ef3759f5e 100644 --- a/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/style.scss +++ b/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/style.scss @@ -56,3 +56,7 @@ } } } + +.payone-config-reaload__btn { + margin: 15px 0; +} diff --git a/src/Resources/app/administration/src/module/payone-payment/snippet/de_DE.json b/src/Resources/app/administration/src/module/payone-payment/snippet/de_DE.json index 91129f8ee..3dd7dfe4e 100644 --- a/src/Resources/app/administration/src/module/payone-payment/snippet/de_DE.json +++ b/src/Resources/app/administration/src/module/payone-payment/snippet/de_DE.json @@ -3,7 +3,29 @@ "title": "PAYONE", "general": { "mainMenuItemGeneral": "PAYONE", - "descriptionTextModule": "Einstellungen für PAYONE" + "descriptionTextModule": "Einstellungen für PAYONE", + "headlines": { + "ratepayProfiles": "Profile", + "ratepayProfileConfigurations": "Profil-Konfigurationen" + }, + "label": { + "shopId": "Shop-ID", + "currency": "Währung", + "error": "Status", + "invoiceCountry": "Rechnungsland", + "shippingCountry": "Lieferland", + "minBasket": "Min. Warenkorb", + "maxBasket": "Max. Warenkorb", + "reloadConfigBtn": "Profil-Konfiguration neu laden", + "reloadConfigInfo": "(Änderungen an der Plugin-Konfiguration werden dabei zuerst gespeichert)" + }, + "actions": { + "addShop": "Shop-ID hinzufügen" + }, + "errors": { + "existingShopId": "Die eingegebene ShopId existiert bereits.", + "emptyInputs": "Bitte füllen Sie alle Eingabefelder aus." + } }, "capture": { "buttonTitle": "Capture", @@ -60,6 +82,9 @@ "titleError": "Fehler", "labelShowSpecificStatusMapping": "Statusmappingkonfiguration einblenden", "helpTextShowSpecificStatusMapping": "Sie können für jede Zahlungsart ein spezifisches Statusmapping konfigurieren. Existiert eine solche Konfiguration nicht, wird auf die allgemeine Konfiguration zurückgegriffen.", + "messageSaveError": { + "ratepayProfilesUpdateFailed": "Mindestens ein Ratepay Profil konnte nicht erfolgreich gespeichert werden, bitte prüfen Sie Ihre Konfiguration." + }, "messageTestSuccess": "Die API-Zugangsdaten wurden erfolgreich validiert.", "messageTestNoTestedPayments": "Bei der Prüfung wurden keine Zahlarten getestet, weil keine der PAYONE Zahlarten aktiviert ist. Bitte aktivieren Sie mindestens eine PAYONE Zahlart unter Einstellungen --> Shop --> Zahlungsarten.", "messageTestError": { @@ -80,7 +105,10 @@ "paydirekt": "Die API-Zugangsdaten für PAYONE paydirekt sind nicht korrekt.", "trustly": "Die API-Zugangsdaten für PAYONE Trustly sind nicht korrekt.", "applePay": "Die API-Zugangsdaten für PAYONE Apple Pay sind nicht korrekt.", - "bancontact": "Die API-Zugangsdaten für PAYONE Bancontact sind nicht korrekt." + "bancontact": "Die API-Zugangsdaten für PAYONE Bancontact sind nicht korrekt.", + "ratepayDebit": "Die API-Zugangsdaten für PAYONE Ratepay Lastschrift sind nicht korrekt.", + "ratepayInstallment": "Die API-Zugangsdaten für PAYONE Ratepay Ratenzahlung sind nicht korrekt.", + "ratepayInvoicing": "Die API-Zugangsdaten für PAYONE Ratepay Rechnungskauf sind nicht korrekt." } }, "supportModal": { diff --git a/src/Resources/app/administration/src/module/payone-payment/snippet/en_GB.json b/src/Resources/app/administration/src/module/payone-payment/snippet/en_GB.json index 9a9963806..45abe48af 100644 --- a/src/Resources/app/administration/src/module/payone-payment/snippet/en_GB.json +++ b/src/Resources/app/administration/src/module/payone-payment/snippet/en_GB.json @@ -3,7 +3,29 @@ "title": "PAYONE", "general": { "mainMenuItemGeneral": "PAYONE", - "descriptionTextModule": "Settings for PAYONE" + "descriptionTextModule": "Settings for PAYONE", + "headlines": { + "ratepayProfiles": "Profile", + "ratepayProfileConfigurations": "Profil-Konfigurationen" + }, + "label": { + "shopId": "Shop-ID", + "currency": "Currency", + "error": "Status", + "invoiceCountry": "Invoice Country", + "shippingCountry": "Shipping Country", + "minBasket": "Min. Basket", + "maxBasket": "Max. Basket", + "reloadConfigBtn": "Reload Profile Configuration", + "reloadConfigInfo": "(Plugin Configuration Changes will be saved first)" + }, + "actions": { + "addShop": "Add Shop-ID" + }, + "errors": { + "existingShopId": "The entered shop-id already exists.", + "emptyInputs": "Please fill all input fields." + } }, "capture": { "buttonTitle": "Capture", @@ -60,6 +82,9 @@ "titleError": "Error", "labelShowSpecificStatusMapping": "Display state mapping configuration", "helpTextShowSpecificStatusMapping": "If not configured the general status mapping config will be applied.", + "messageSaveError": { + "ratepayProfilesUpdateFailed": "At least one Ratepay profile could not be saved successfully, please check your configuration." + }, "messageTestSuccess": "The API credentials were verified successfully.", "messageTestNoTestedPayments": "No payment methods were tested during the check because none of the PAYONE payment methods are activated. Please activate at least one PAYONE payment method under Settings --> Shop --> Payment.", "messageTestError": { @@ -80,7 +105,10 @@ "paydirekt": "The API credentials for PAYONE paydirekt are not valid.", "trustly": "The API credentials for PAYONE Trustly are not valid.", "applePay": "The API credentials for PAYONE Apple Pay are not valid.", - "bancontact": "The API credentials for PAYONE Bancontact payment are not valid." + "bancontact": "The API credentials for PAYONE Bancontact payment are not valid.", + "ratepayDebit": "The API credentials for PAYONE Ratepay Direct Debit payment are not valid.", + "ratepayInstallment": "The API credentials for PAYONE Ratepay Installments payment are not valid.", + "ratepayInvoicing": "The API credentials for PAYONE Ratepay Open Invoice payment are not valid." } }, "supportModal": { diff --git a/src/Resources/app/storefront/dist/storefront/js/payone-payment.js b/src/Resources/app/storefront/dist/storefront/js/payone-payment.js index af82fb97a..ffdf3814e 100644 --- a/src/Resources/app/storefront/dist/storefront/js/payone-payment.js +++ b/src/Resources/app/storefront/dist/storefront/js/payone-payment.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([["payone-payment"],{rZg5:function(e,t,n){"use strict";n.r(t);var r=n("FGIj"),o=n("477Q");function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function a(e){return function(e){if(Array.isArray(e))return l(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return l(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return l(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0)return!0;if(!this.iframe.isComplete()){var r=document.getElementById("iframeErrorOutput");return this.iframeFieldCheckerStarted||setInterval((function(){t.iframe.isComplete()?r.style.display="none":r.style.display="block"}),250),this.iframeFieldCheckerStarted=!0,this._handleOrderFormError(e),!1}return this.orderFormDisabled?(window.payoneCreditCardCheckCallback=this._payoneCheckCallback.bind(this),this.iframe.creditCardCheck("payoneCreditCardCheckCallback"),this._handleOrderFormError(e),!1):void 0}},{key:"_handleOrderFormError",value:function(e){var t=document.getElementById("confirmFormSubmit");if(e.preventDefault(),t){var n=new o.a(t);t.disabled=!1,n.remove()}}},{key:"_handleChangeSavedCard",value:function(){var e=document.getElementById("savedpseudocardpan");e.options[e.selectedIndex].value?a(document.getElementsByClassName("credit-card-input")).forEach((function(e){e.classList.add("hide")})):a(document.getElementsByClassName("credit-card-input")).forEach((function(e){e.classList.remove("hide")}))}},{key:"_payoneCheckCallback",value:function(e){if("VALID"===e.status)document.getElementById("pseudocardpan").value=e.pseudocardpan,document.getElementById("truncatedcardpan").value=e.truncatedcardpan,document.getElementById("cardexpiredate").value=e.cardexpiredate,this.orderFormDisabled=!1,document.getElementById("confirmOrderForm").submit();else{var t=document.getElementById("confirmFormSubmit"),n=document.getElementById("errorOutput");t.removeAttribute("disabled"),n.innerHTML=e.errormessage,n.style.display="block"}}}])&&s(n.prototype,r),i&&s(n,i),t}(r.a);f={supportedCardtypes:["#","V","A","M","D","J","O","U","P"]},(p="options")in(m=h)?Object.defineProperty(m,p,{value:f,enumerable:!0,configurable:!0,writable:!0}):m[p]=f;var v=n("2Jwc"),b=n("3xtq"),g=n("k8s9");function _(e){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function k(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function E(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0)return!0;if(!this.iframe.isComplete()){var r=document.getElementById("iframeErrorOutput");return this.iframeFieldCheckerStarted||setInterval((function(){t.iframe.isComplete()?r.style.display="none":r.style.display="block"}),250),this.iframeFieldCheckerStarted=!0,this._handleOrderFormError(e),!1}return this.orderFormDisabled?(window.payoneCreditCardCheckCallback=this._payoneCheckCallback.bind(this),this.iframe.creditCardCheck("payoneCreditCardCheckCallback"),this._handleOrderFormError(e),!1):void 0}},{key:"_handleOrderFormError",value:function(e){var t=document.getElementById("confirmFormSubmit");if(e.preventDefault(),t){var n=new a.a(t);t.disabled=!1,n.remove()}}},{key:"_handleChangeSavedCard",value:function(){var e=document.getElementById("savedpseudocardpan");e.options[e.selectedIndex].value?i(document.getElementsByClassName("credit-card-input")).forEach((function(e){e.classList.add("hide")})):i(document.getElementsByClassName("credit-card-input")).forEach((function(e){e.classList.remove("hide")}))}},{key:"_payoneCheckCallback",value:function(e){if("VALID"===e.status)document.getElementById("pseudocardpan").value=e.pseudocardpan,document.getElementById("truncatedcardpan").value=e.truncatedcardpan,document.getElementById("cardexpiredate").value=e.cardexpiredate,this.orderFormDisabled=!1,document.getElementById("confirmOrderForm").submit();else{var t=document.getElementById("confirmFormSubmit"),n=document.getElementById("errorOutput");t.removeAttribute("disabled"),n.innerHTML=e.errormessage,n.style.display="block"}}}])&&s(n.prototype,r),o&&s(n,o),t}(r.a);f={supportedCardtypes:["#","V","A","M","D","J","O","U","P"]},(m="options")in(p=h)?Object.defineProperty(p,m,{value:f,enumerable:!0,configurable:!0,writable:!0}):p[m]=f;var v=n("2Jwc"),b=n("3xtq"),g=n("k8s9");function _(e){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function I(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function k(e,t){for(var n=0;n this._handleCalculationCallback(response)); + } + + _handleCalculationCallback(response) { + this._replaceCalculationContent(response); + } + + _replaceCalculationContent(response){ + const ratepayInstallmentPlanContainer = DomAccess.querySelector(document, this.options.ratepayInstallmentPlanContainerSelector); + + ratepayInstallmentPlanContainer.innerHTML = response; + + this.ratepayInstallmentTable = DomAccess.querySelector(document, this.options.ratepayInstallmentTableSelector); + + this.ratepayRuntimeInput.value = this.ratepayInstallmentTable.dataset.ratepayNumberOfRates; + this.ratepayRateInput.value = this.ratepayInstallmentTable.dataset.ratepayRate; + } + + _handleOpenedIbanContainer() { + this.ratepayIbanInput.required = true; + } + + _handleClosedIbanContainer() { + this.ratepayIbanInput.required = false; + } +} diff --git a/src/Resources/app/storefront/src/scss/base.scss b/src/Resources/app/storefront/src/scss/base.scss index 5ad54edfe..3f8f8b2d2 100644 --- a/src/Resources/app/storefront/src/scss/base.scss +++ b/src/Resources/app/storefront/src/scss/base.scss @@ -93,3 +93,56 @@ apple-pay-button { font-size: 0.8rem; } } + + +.payone-payment.ratepay-installment { + .show-calculation-btn { + .show-calculation { + display: none; + } + + .hide-calculation { + display: block; + } + + &.collapsed { + .show-calculation { + display: block; + } + + .hide-calculation { + display: none; + } + } + } + + .payone-ratepay-installment-iban-toggle { + .payone-ratepay-collapsed-text { + display: none; + } + + .payone-ratepay-open-text { + display: block; + } + + &.collapsed { + .payone-ratepay-collapsed-text { + display: block; + } + + .payone-ratepay-open-text { + display: none; + } + } + } + + .ratepay-installment-installment-calculation { + table { + tr { + td:last-child { + text-align: right; + } + } + } + } +} diff --git a/src/Resources/config/routes.xml b/src/Resources/config/routes.xml index 0e0d0de7c..a7aa60354 100644 --- a/src/Resources/config/routes.xml +++ b/src/Resources/config/routes.xml @@ -18,6 +18,8 @@ + + diff --git a/src/Resources/config/settings.xml b/src/Resources/config/settings.xml index e5eb5d8ec..261c31918 100644 --- a/src/Resources/config/settings.xml +++ b/src/Resources/config/settings.xml @@ -2824,4 +2824,200 @@ + + + PAYONE Ratepay Open Invoice + PAYONE Ratepay Rechnungskauf + + payment_ratepay_invoicing + + + ratepayInvoicingMerchantId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayInvoicingAccountId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayInvoicingPortalId + + You need an ID to a separate payment gateway to use this payment method. + Sie benötigen eine ID zu einem separates Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayInvoicingPortalKey + + You need a key to a separate payment gateway to use this payment method. + Sie benötigen einen Schlüssel zu einem separaten Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayInvoicingAuthorizationMethod + + + Use this option to set the authorization method for this payment type. + Legt die Autorisierungsmethode für diese Zahlungsart fest. + + + + + + + + ratepayInvoicingDeviceFingerprintSnippetId + + + ratepay + + + + ratepayInvoicingProfiles + + + + ratepayInvoicingProfileConfigurations + + + + + PAYONE Ratepay Direct Debit + PAYONE Ratepay Lastschrift + + payment_ratepay_debit + + + ratepayDebitMerchantId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayDebitAccountId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayDebitPortalId + + You need an ID to a separate payment gateway to use this payment method. + Sie benötigen eine ID zu einem separates Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayDebitPortalKey + + You need a key to a separate payment gateway to use this payment method. + Sie benötigen einen Schlüssel zu einem separaten Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayDebitAuthorizationMethod + + + Use this option to set the authorization method for this payment type. + Legt die Autorisierungsmethode für diese Zahlungsart fest. + + + + + + + + ratepayDebitProfiles + + + + ratepayDebitProfileConfigurations + + + + + PAYONE Ratepay Installments + PAYONE Ratepay Ratenkauf + + payment_ratepay_installment + + + ratepayInstallmentMerchantId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayInstallmentAccountId + + Uses the basic configuration value if nothing is entered here. + Nutzt den Wert der Grundeinstellungen, falls nichts eingetragen wird. + + + + ratepayInstallmentPortalId + + You need an ID to a separate payment gateway to use this payment method. + Sie benötigen eine ID zu einem separates Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayInstallmentPortalKey + + You need a key to a separate payment gateway to use this payment method. + Sie benötigen einen Schlüssel zu einem separaten Zahlungsportal um diese Zahlart verwenden zu können. + + + + ratepayInstallmentAuthorizationMethod + + + Use this option to set the authorization method for this payment type. + Legt die Autorisierungsmethode für diese Zahlungsart fest. + + + + + + + + ratepayInstallmentProfiles + + + + ratepayInstallmentProfileConfigurations + + diff --git a/src/Resources/public/administration/css/payone-payment.css b/src/Resources/public/administration/css/payone-payment.css index 19a57c630..d61022e86 100644 --- a/src/Resources/public/administration/css/payone-payment.css +++ b/src/Resources/public/administration/css/payone-payment.css @@ -1 +1 @@ -.payone-payment-detail--capture-modal .sw-modal__body{padding:0}.payone-payment-detail--capture-modal .sw-modal__footer{border-top:1px solid #d1d9e0}.payone-payment-detail--capture-modal .payone-payment-detail--capture-modal--content,.payone-payment-detail--capture-modal .payone-payment-detail--refund-modal--content{padding:20px 30px}.payone-payment-detail--capture-modal .payone-payment-detail--capture-modal--checkbox-shipping-costs{margin-top:3.5rem}.payone-payment-detail--refund-modal .sw-modal__body{padding:0}.payone-payment-detail--refund-modal .sw-modal__footer{border-top:1px solid #d1d9e0}.payone-payment-detail--refund-modal .payone-payment-detail--capture-modal--content,.payone-payment-detail--refund-modal .payone-payment-detail--refund-modal--content{padding:20px 30px}.payone-order-items .sw-data-grid__bulk{display:none}.payone-payment-plugin-icon{height:100%}.payone-feedback__col{padding:0 10px;text-align:center;border-left:1px solid #888}.payone-feedback__icon{margin-bottom:25px}.payone-feedback__icon .sw-icon.sw-icon--large{width:50px;height:50px}.payone-feedback .payone-feedback__col:first-child{border-left:none}.payone-feedback .payone-feedback__desc{font-size:1.1em;letter-spacing:.75px;margin-bottom:25px}.payone-config__wrapper .sw-card .payone-config__collapsible-container{text-align:right}.payone-config__wrapper .sw-card .payone-config__collapsible-container:not(.collapsed){margin-bottom:22px}.payone-config__wrapper .sw-card .payone-config__collapsible-handle{cursor:pointer;color:#52667a;border:1px solid #d1d9e0;border-radius:4px;display:inline-block;width:28px;height:28px;line-height:0;padding:5px}.payone-config__wrapper .sw-card .payone-config__collapsible-handle:hover{background-color:#e3f3ff}.sw-order-payone-card{line-height:15px}.sw-order-payone-card .payone-payment-detail--notification-forwards{margin-top:30px}.sw-order-payone-card dd,.sw-order-payone-card dt{padding:0;border-bottom:none}.sw-order-payone-card dt{font-weight:600}.sw-order-payone-card dt:not(:first-child),.sw-order-payone-card dt:only-of-type{padding-top:10px}.payone-context-button__button{height:48px;line-height:40px}.sw-settings-index__payone-icon{height:40px} \ No newline at end of file +.payone-ratepay-profile-configurations{margin-top:20px}@media screen and (min-width:768px){.payone-ratepay-profile-configurations{width:50%}}.payone-ratepay-profile-configurations .payone-ratepay-profile-configuration--headline{font-weight:600;margin-top:20px}.payone-ratepay-profile-configurations .sw-description-list dt{text-align:right}.payone-ratepay-profiles .sw-alert{margin:20px auto;width:100%}.payone-payment-detail--capture-modal .sw-modal__body{padding:0}.payone-payment-detail--capture-modal .sw-modal__footer{border-top:1px solid #d1d9e0}.payone-payment-detail--capture-modal .payone-payment-detail--capture-modal--content,.payone-payment-detail--capture-modal .payone-payment-detail--refund-modal--content{padding:20px 30px}.payone-payment-detail--capture-modal .payone-payment-detail--capture-modal--checkbox-shipping-costs{margin-top:3.5rem}.payone-payment-detail--refund-modal .sw-modal__body{padding:0}.payone-payment-detail--refund-modal .sw-modal__footer{border-top:1px solid #d1d9e0}.payone-payment-detail--refund-modal .payone-payment-detail--capture-modal--content,.payone-payment-detail--refund-modal .payone-payment-detail--refund-modal--content{padding:20px 30px}.payone-order-items .sw-data-grid__bulk{display:none}.payone-payment-plugin-icon{height:100%}.payone-feedback__col{padding:0 10px;text-align:center;border-left:1px solid #888}.payone-feedback__icon{margin-bottom:25px}.payone-feedback__icon .sw-icon.sw-icon--large{width:50px;height:50px}.payone-feedback .payone-feedback__col:first-child{border-left:none}.payone-feedback .payone-feedback__desc{font-size:1.1em;letter-spacing:.75px;margin-bottom:25px}.payone-config__wrapper .sw-card .payone-config__collapsible-container{text-align:right}.payone-config__wrapper .sw-card .payone-config__collapsible-container:not(.collapsed){margin-bottom:22px}.payone-config__wrapper .sw-card .payone-config__collapsible-handle{cursor:pointer;color:#52667a;border:1px solid #d1d9e0;border-radius:4px;display:inline-block;width:28px;height:28px;line-height:0;padding:5px}.payone-config__wrapper .sw-card .payone-config__collapsible-handle:hover{background-color:#e3f3ff}.payone-config-reaload__btn{margin:15px 0}.sw-order-payone-card{line-height:15px}.sw-order-payone-card .payone-payment-detail--notification-forwards{margin-top:30px}.sw-order-payone-card dd,.sw-order-payone-card dt{padding:0;border-bottom:none}.sw-order-payone-card dt{font-weight:600}.sw-order-payone-card dt:not(:first-child),.sw-order-payone-card dt:only-of-type{padding-top:10px}.payone-context-button__button{height:48px;line-height:40px}.sw-settings-index__payone-icon{height:40px} \ No newline at end of file diff --git a/src/Resources/public/administration/js/payone-payment.js b/src/Resources/public/administration/js/payone-payment.js index 961c856d9..64aa95059 100644 --- a/src/Resources/public/administration/js/payone-payment.js +++ b/src/Resources/public/administration/js/payone-payment.js @@ -1 +1 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var a=t[i]={i:i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(i,a,function(t){return e[t]}.bind(null,a));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/bundles/payonepayment/",n(n.s="UZdK")}({"2O5J":function(e){e.exports=JSON.parse('{"payonePayment":{"notificationTarget":{"module":{"title":"Payone notification forward","buttonTitle":"Notifications"},"list":{"title":"Notification forward","empty":"No entries","buttonCreate":"Add new notification target"},"detail":{"headline":"Notification forward","placeholder":{"url":"Url","username":"Username","password":"Password"},"label":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions","buttonSave":"Save","buttonCancel":"Cancel","username":"Username","password":"Password"}},"columns":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions"},"actions":{"requeue":"Requeue"},"messages":{"success":"The notification forward has been successfully queued."}}}}')},"2f31":function(e,t){e.exports='{% block payone_notification_target_detail %}\n \n\n {% block payone_notification_target_detail_header %}\n \n {% endblock %}\n\n {% block payone_notification_target_detail_actions %}\n \n {% endblock %}\n\n {% block payone_notification_target_detail_content %}\n \n\n {% block payone_notification_target_detail_base_basic_info_card %}\n \n \n \n {% endblock %}\n \n {% endblock %}\n\n \n{% endblock %}\n'},"3U21":function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:"payone_payment";return i(this,l),c.call(this,e,t,n)}return t=l,(n=[{key:"validateApiCredentials",value:function(e){var t=this.getBasicHeaders();return this.httpClient.post("_action/".concat(this.getApiBasePath(),"/validate-api-credentials"),{credentials:e},{headers:t}).then((function(e){return u.handleResponse(e)}))}},{key:"getStateMachineTransitionActions",value:function(){var e=this.getBasicHeaders();return this.httpClient.get("_action/".concat(this.getApiBasePath(),"/get-state-machine-transition-actions"),{headers:e}).then((function(e){return u.handleResponse(e)}))}},{key:"hasApplePayCert",value:function(){var e=this.getBasicHeaders();return this.httpClient.get("_action/".concat(this.getApiBasePath(),"/check-apple-pay-cert"),{headers:e}).catch((function(){return!1})).then((function(e){return!!e}))}}])&&a(t.prototype,n),s&&a(t,s),Object.defineProperty(t,"prototype",{writable:!1}),l}(u);l.addServiceProvider("PayonePaymentSettingsService",(function(e){var t=l.getContainer("init");return new d(t.httpClient,e.loginService)}))},"3nqX":function(e,t,n){var i=n("K+0n");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("9e189240",i,!0,{})},"4GG1":function(e,t,n){var i=n("Gc8S");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("15e19ffa",i,!0,{})},"78OT":function(e,t){try{Shopware.Service("privileges").addPrivilegeMappingEntry({category:"additional_permissions",parent:null,key:"Payone",roles:{payone_order_management:{privileges:["order_transaction:update","order_line_item:update","state_machine_history:create",Shopware.Service("privileges").getPrivileges("order.viewer")],dependencies:[]}}})}catch(e){}},"8KF6":function(e,t,n){},"9Sjd":function(e,t){e.exports='{% block payone_payment_payment_details %}\n
\n \n \n {{ $tc(\'payone-payment.capture.buttonTitle\') }}\n \n \n\n \n \n \n\n
\n \n \n \n \n \n \n
\n\n \n
\n
\n{% endblock %}\n'},CPMY:function(e,t,n){},FCfm:function(e,t,n){var i=n("qSh7");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("09344dd6",i,!0,{})},GGZ9:function(e,t){var n=Shopware.Filter,i=Shopware.Utils.format.currency;n.register("payone_currency",(function(e,t,n,a){return null===e?"-":(n||(n=0),e/=Math.pow(10,n),i(e,t,a))}))},Gc8S:function(e,t,n){},HvTO:function(e,t,n){var i=n("cm4w");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("d882c8f0",i,!0,{})},IvS7:function(e){e.exports=JSON.parse('{"payone-payment":{"title":"PAYONE","general":{"mainMenuItemGeneral":"PAYONE","descriptionTextModule":"Einstellungen für PAYONE"},"capture":{"buttonTitle":"Capture","successTitle":"PAYONE","successMessage":"Capture erfolgreich durchgeführt.","errorTitle":"PAYONE","errorMessage":"Capture konnte nicht durchgeführt werden.","tooltips":{"impossible":"Einzug unmöglich"}},"refund":{"buttonTitle":"Refund","successTitle":"PAYONE","successMessage":"Refund erfolgreich durchgeführt.","errorTitle":"PAYONE","errorMessage":"Refund konnte nicht durchgeführt werden.","tooltips":{"impossible":"Erstattung unmöglich"}},"modal":{"capture":{"title":"Einzug","submit":"Einziehen","fullSubmit":"Alles Einziehen","amount":"Einzugswert","captured":"Eingezogener Wert"},"refund":{"title":"Erstattung","submit":"Erstatten","fullSubmit":"Alles Erstatten","amount":"Erstattungswert","refunded":"Erstatteter Wert"},"close":"Schließen","orderAmount":"Bestellungswert","remainingAmount":"Ausstehender Wert","shippingCosts":"Versandkosten","labelComment":"Label comment","descriptionHelpText":"Description help text","columns":{"reference":"Referenz","product":"Produkt","quantity":"Anzahl","price":"Preis"}},"settingsForm":{"save":"Speichern","test":"API-Zugangsdaten testen","titleSuccess":"Erfolg","titleError":"Fehler","labelShowSpecificStatusMapping":"Statusmappingkonfiguration einblenden","helpTextShowSpecificStatusMapping":"Sie können für jede Zahlungsart ein spezifisches Statusmapping konfigurieren. Existiert eine solche Konfiguration nicht, wird auf die allgemeine Konfiguration zurückgegriffen.","messageTestSuccess":"Die API-Zugangsdaten wurden erfolgreich validiert.","messageTestNoTestedPayments":"Bei der Prüfung wurden keine Zahlarten getestet, weil keine der PAYONE Zahlarten aktiviert ist. Bitte aktivieren Sie mindestens eine PAYONE Zahlart unter Einstellungen --\x3e Shop --\x3e Zahlungsarten.","messageTestError":{"general":"Die API-Zugangsdaten konnten nicht validiert werden.","creditCard":"Die API-Zugangsdaten für PAYONE Kreditkarte sind nicht korrekt.","prepayment":"Die API-Zugangsdaten für PAYONE Vorkasse sind nicht korrekt.","debit":"Die API-Zugangsdaten für PAYONE Lastschrift sind nicht korrekt.","paypalExpress":"Die API-Zugangsdaten für PAYONE PayPal Express sind nicht korrekt.","paypal":"Die API-Zugangsdaten für PAYONE PayPal sind nicht korrekt.","payolutionInstallment":"Die API-Zugangsdaten für PAYONE Unzer Ratenkauf sind nicht korrekt.","payolutionInvoicing":"Die API-Zugangsdaten für PAYONE Unzer Rechnungskauf sind nicht korrekt.","payolutionDebit":"Die API-Zugangsdaten für PAYONE Unzer Lastschrift sind nicht korrekt.","sofort":"Die API-Zugangsdaten für PAYONE Sofort Überweisung sind nicht korrekt.","eps":"Die API-Zugangsdaten für PAYONE eps Überweisung sind nicht korrekt.","iDeal":"Die API-Zugangsdaten für PAYONE iDEAL sind nicht korrekt.","secureInvoice":"Die API-Zugangsdaten für PAYONE Gesicherter Rechnungskauf sind nicht korrekt.","openInvoice":"Die API-Zugangsdaten für PAYONE Rechnungskauf sind nicht korrekt.","paydirekt":"Die API-Zugangsdaten für PAYONE paydirekt sind nicht korrekt.","trustly":"Die API-Zugangsdaten für PAYONE Trustly sind nicht korrekt.","applePay":"Die API-Zugangsdaten für PAYONE Apple Pay sind nicht korrekt.","bancontact":"Die API-Zugangsdaten für PAYONE Bancontact sind nicht korrekt."}},"supportModal":{"menuButton":"Support","title":"Wie können wir Ihnen helfen?","documentation":{"description":"Lesen Sie unsere Online-Dokumentation","button":"Dokumentation"},"support":{"description":"Kontaktieren Sie unseren Support","button":"Technischer Support"},"repository":{"description":"Melden Sie Fehler und Verbesserungen","button":"GitHub"},"testdata":{"description":"Erstellen Sie hier Ihre persönlichen Testdaten","button":"Testdaten"}},"applePay":{"cert":{"notification":"Für die Nutzung von ApplePay ist ein Zertifikat/Key-Paar zur Authentifizierung des Merchants erforderlich. Die Anlage eines solchen Zertifikats wird hier beschrieben:
\\n https://docs.payone.com/display/public/PLATFORM/Special+Remarks+-+Apple+Pay#SpecialRemarks-ApplePay-Onboarding

\\n\\n Erstellen Sie im Anschluss unter Verwendung des folgenden Befehls eine PEM-Datei des Zertifikates:
\\n
openssl x509 -inform der -in merchant_id.cer -out merchant_id.pem

\\n Hinterlegen Sie das Zertifikat (merchant_id.pem) und den Key (merchant_id.key) in folgendem Verzeichnis:
\\n
%shopwareRoot%/config/apple-pay-cert
"}},"transitionActionNames":{"cancel":"Stornieren","complete":"Abschließen","pay":"Bezahlen","pay_partially":"Teilweise bezahlen","process":"Durchführen","refund":"Rückerstatten","refund_partially":"Teilweise rückerstatten","remind":"Erinnern","reopen":"Wieder öffnen","retour":"Retoure","retour_partially":"Teilweise retounieren","ship":"Versenden","ship_partially":"Teilweise versenden"},"messageNotBlank":"Dieser Wert darf nicht leer sein.","txid":"TXID","sequenceNumber":{"label":"Sequenznummer","empty":"keine"},"transactionState":"Status","transactionCancelled":"Transaktion in Shopware abgebrochen","error":{"transaction":{"notFound":"Es wurde keine passende Transaktion gefundend","orderNotFound":"Es wurde keine passende Bestellung gefundend"}}},"sw-privileges":{"additional_permissions":{"Payone":{"label":"PAYONE","payone_order_management":"PAYONE Transaktionsmanagement"}}}}')},"K+0n":function(e,t,n){},KCDJ:function(e,t,n){var i=n("8KF6");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("74f42fc6",i,!0,{})},LmWz:function(e,t){e.exports='{% block sw_settings_content_card_slot_plugins %}\n {% parent %}\n\n \n \n \n{% endblock %}\n'},SZ7m:function(e,t,n){"use strict";function i(e,t){for(var n=[],i={},a=0;an.parts.length&&(i.parts.length=n.parts.length)}else{var r=[];for(a=0;a0&&this.capturedAmount>0||this.transaction.customFields.payone_allow_capture)},isItemSelected:function(){var e=!1;return this.selection.forEach((function(t){t.selected&&(e=!0)})),e},hasRemainingShippingCosts:function(){var e=this;if(this.order.shippingCosts.totalPrice<=0)return!1;var t=this.order.shippingCosts.totalPrice*Math.pow(10,this.decimalPrecision),n=0;return this.order.lineItems.forEach((function(t){t.customFields&&t.customFields.payone_captured_quantity&&0=t)}},data:function(){return{isLoading:!1,hasError:!1,showCaptureModal:!1,isCaptureSuccessful:!1,selection:[],captureAmount:0,includeShippingCosts:!1}},methods:{calculateCaptureAmount:function(){var e=0;this.selection.forEach((function(t){t.selected&&(e+=t.unit_price*t.quantity)})),e>this.remainingAmount&&(e=this.remainingAmount),this.captureAmount=e},openCaptureModal:function(){this.showCaptureModal=!0,this.isCaptureSuccessful=!1,this.selection=[]},closeCaptureModal:function(){this.showCaptureModal=!1},onCaptureFinished:function(){this.isCaptureSuccessful=!1},captureOrder:function(){var e=this,t={orderTransactionId:this.transaction.id,payone_order_id:this.transaction.customFields.payone_transaction_id,salesChannel:this.order.salesChannel,amount:this.captureAmount,orderLines:[],complete:this.captureAmount===this.remainingAmount,includeShippingCosts:!1};this.isLoading=!0,this.selection.forEach((function(n){e.order.lineItems.forEach((function(e){if(e.id===n.id&&n.selected&&00&&this.selection.push({id:"shipping",quantity:1,unit_price:this.order.shippingCosts.totalPrice,selected:!1})}}});var u=n("ZS2F"),d=n.n(u);n("mJGU");function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var f=Shopware,y=f.Component,h=f.Mixin;y.register("payone-refund-button",{template:d.a,mixins:[h.getByName("notification")],inject:["PayonePaymentService"],props:{order:{type:Object,required:!0},transaction:{type:Object,required:!0}},data:function(){return{isLoading:!1,hasError:!1,showRefundModal:!1,isRefundSuccessful:!1,selection:[],refundAmount:0,includeShippingCosts:!1}},computed:{decimalPrecision:function(){return this.order&&this.order.currency?this.order.currency.decimalPrecision?this.order.currency.decimalPrecision:this.order.currency.itemRounding?this.order.currency.itemRounding.decimals:void 0:2},remainingAmount:function(){return void 0===this.transaction.customFields||void 0===this.transaction.customFields.payone_captured_amount?0:this.transaction.customFields.payone_captured_amount-this.refundedAmount},refundedAmount:function(){return void 0===this.transaction.customFields||void 0===this.transaction.customFields.payone_refunded_amount?0:this.transaction.customFields.payone_refunded_amount},maxRefundAmount:function(){return this.remainingAmount/Math.pow(10,this.decimalPrecision)},buttonEnabled:function(){return!!this.transaction.customFields&&(this.remainingAmount>0&&this.refundedAmount>0||this.transaction.customFields.payone_allow_refund)},hasRemainingRefundableShippingCosts:function(){var e=this;if(this.order.shippingCosts.totalPrice<=0)return!1;var t=this.order.shippingCosts.totalPrice*Math.pow(10,this.decimalPrecision),n=0;return this.order.lineItems.forEach((function(t){t.customFields&&t.customFields.payone_refunded_quantity&&0=t)}},methods:{calculateRefundAmount:function(){var e=0;this.selection.forEach((function(t){t.selected&&(e+=t.unit_price*t.quantity)})),Math.round(e*Math.pow(10,this.decimalPrecision)>this.remainingAmount)&&(e=this.remainingAmount/Math.pow(10,this.decimalPrecision)),this.refundAmount=e},openRefundModal:function(){this.showRefundModal=!0,this.isRefundSuccessful=!1,this.selection=[]},closeRefundModal:function(){this.showRefundModal=!1},onRefundFinished:function(){this.isRefundSuccessful=!1},refundOrder:function(){var e=this,t={orderTransactionId:this.transaction.id,payone_order_id:this.transaction.customFields.payone_transaction_id,salesChannel:this.order.salesChannel,amount:this.refundAmount,orderLines:[],complete:this.refundAmount===this.maxRefundAmount,includeShippingCosts:!1};this.isLoading=!0,this.selection.forEach((function(n){e.order.lineItems.forEach((function(i){if(i.id===n.id&&n.selected&&00&&this.selection.push({id:"shipping",quantity:1,unit_price:this.order.shippingCosts.totalPrice,selected:!1})}}});var g=n("bqMO"),b=n.n(g);n("4GG1");Shopware.Component.register("payone-order-items",{template:b.a,props:{order:{type:Object,required:!0},mode:{type:String,required:!1}},computed:{orderItems:function(){var e=this,t=[];return this.order.lineItems.forEach((function(n){var i=e.$options.filters.currency(n.totalPrice,e.order.currency.shortName,e.order.decimal_precision),a=!1,o=n.quantity;n.customFields&&("refund"===e.mode?(n.customFields.payone_captured_quantity&&0>n.customFields.payone_captured_quantity&&(o=n.customFields.payone_captured_quantity),n.customFields.payone_refunded_quantity&&(o-=n.customFields.payone_refunded_quantity)):"capture"===e.mode&&n.customFields.payone_captured_quantity&&0o&&(a=!0),t.push({id:n.id,product:n.label,quantity:o,disabled:a,selected:!1,price:i,orderItem:n})})),this.order.shippingCosts.totalPrice>0&&t.push({id:"shipping",product:this.$tc("payone-payment.modal.shippingCosts"),quantity:1,disabled:!1,selected:!1,price:this.$options.filters.currency(this.order.shippingCosts.totalPrice,this.order.currency.shortName,this.order.decimal_precision),orderItem:{}}),t},orderItemColumns:function(){return[{property:"product",label:this.$tc("payone-payment.modal.columns.product"),rawData:!0},{property:"quantity",label:this.$tc("payone-payment.modal.columns.quantity"),rawData:!0},{property:"price",label:this.$tc("payone-payment.modal.columns.price"),rawData:!0}]}},methods:{onSelectItem:function(e,t,n){this.$emit("select-item",t.id,n)},onChangeQuantity:function(e,t){this.$emit("change-quantity",t,e)}}});var _=n("Vxi/"),v=n.n(_);Shopware.Component.extend("payone-data-grid","sw-data-grid",{template:v.a});var w=n("zyFP"),P=n.n(w);n("3nqX");Shopware.Component.register("payone-payment-plugin-icon",{template:P.a});var S=n("dzH1"),k=n.n(S),A=(n("mOqv"),Shopware),C=A.Component,T=A.Mixin,E=Shopware.Utils,O=E.object,x=E.types;C.register("payone-settings",{template:k.a,mixins:[T.getByName("notification"),T.getByName("sw-inline-snippet")],inject:["PayonePaymentSettingsService"],data:function(){return{isLoading:!1,isTesting:!1,isSaveSuccessful:!1,isTestSuccessful:!1,isApplePayCertConfigured:!0,config:{},merchantIdFilled:!1,accountIdFilled:!1,portalIdFilled:!1,portalKeyFilled:!1,showValidationErrors:!1,isSupportModalOpen:!1,stateMachineTransitionActions:[],displayStatusMapping:{},collapsibleState:{status_mapping:!0,payment_credit_card:!0,payment_paypal:!0,payment_paypal_express:!0,payment_debit:!0,payment_sofort:!0,payment_payolution_installment:!0,payment_payolution_invoicing:!0,payment_payolution_debit:!0,payment_eps:!0,payment_ideal:!0,payment_paydirekt:!0,payment_prepayment:!0,payment_trustly:!0,payment_secure_invoice:!0,payment_open_invoice:!0,payment_apple_pay:!0,payment_bancontact:!0}}},created:function(){this.createdComponent()},computed:{credentialsMissing:function(){return!(this.merchantIdFilled&&this.accountIdFilled&&this.portalIdFilled&&this.portalKeyFilled)}},metaInfo:function(){return{title:this.$createTitle()}},methods:{createdComponent:function(){var e=this,t=this;this.PayonePaymentSettingsService.getStateMachineTransitionActions().then((function(e){e.data.forEach((function(e){var n="payone-payment.transitionActionNames."+e.label,i=t.$t(n);i===n&&(i=e.label),t.stateMachineTransitionActions.push({label:i,value:e.value})}))})),this.PayonePaymentSettingsService.hasApplePayCert().then((function(t){e.isApplePayCertConfigured=t}))},paymentMethodPrefixes:function(){return["creditCard","debit","paypal","paypalExpress","payolutionInvoicing","payolutionInstallment","payolutionDebit","sofort","eps","iDeal","paydirekt","prepayment","trustly","secureInvoice","openInvoice","applePay","bancontact"]},isVisiblePaymentMethodCard:function(e){return e.name.startsWith("payment")&&!this.isCollapsed(e)},isCollapsible:function(e){return e.name in this.collapsibleState},displayField:function(e,t,n){return!(n.name in this.collapsibleState)||!this.collapsibleState[n.name]},isCollapsed:function(e){return this.collapsibleState[e.name]},toggleCollapsible:function(e){e.name in this.collapsibleState&&(this.collapsibleState[e.name]=!this.collapsibleState[e.name])},saveFinish:function(){this.isSaveSuccessful=!1},testFinish:function(){this.isTestSuccessful=!1},onConfigChange:function(e){this.config=e,this.checkCredentialsFilled(),this.showValidationErrors=!1},checkCredentialsFilled:function(){this.merchantIdFilled=!!this.getConfigValue("merchantId"),this.accountIdFilled=!!this.getConfigValue("accountId"),this.portalIdFilled=!!this.getConfigValue("portalId"),this.portalKeyFilled=!!this.getConfigValue("portalKey")},getConfigValue:function(e){var t=this.$refs.systemConfig.actualConfigData.null;return null===this.$refs.systemConfig.currentSalesChannelId?this.config["PayonePayment.settings.".concat(e)]:this.config["PayonePayment.settings.".concat(e)]||t["PayonePayment.settings.".concat(e)]},getPaymentConfigValue:function(e,t){var n=e.charAt(0).toUpperCase()+e.slice(1);return this.getConfigValue(t+n)||this.getConfigValue(e)},onSave:function(){var e=this;this.credentialsMissing?this.showValidationErrors=!0:(this.isSaveSuccessful=!1,this.isLoading=!0,this.$refs.systemConfig.saveAll().then((function(){e.isLoading=!1,e.isSaveSuccessful=!0})).catch((function(){e.isLoading=!1})))},onTest:function(){var e=this;this.isTesting=!0,this.isTestSuccessful=!1;var t={};this.paymentMethodPrefixes().forEach((function(n){t[n]={merchantId:e.getPaymentConfigValue("merchantId",n),accountId:e.getPaymentConfigValue("accountId",n),portalId:e.getPaymentConfigValue("portalId",n),portalKey:e.getPaymentConfigValue("portalKey",n)}})),this.PayonePaymentSettingsService.validateApiCredentials(t).then((function(t){var n=t.testCount,i=t.credentialsValid,a=t.errors;if(i)e.createNotificationSuccess({title:e.$tc("payone-payment.settingsForm.titleSuccess"),message:n>0?e.$tc("payone-payment.settingsForm.messageTestSuccess"):e.$tc("payone-payment.settingsForm.messageTestNoTestedPayments")}),e.isTestSuccessful=!0;else for(var o in a)a.hasOwnProperty(o)&&e.createNotificationError({title:e.$tc("payone-payment.settingsForm.titleError"),message:e.$tc("payone-payment.settingsForm.messageTestError."+o)});e.isTesting=!1})).catch((function(t){e.createNotificationError({title:e.$tc("payone-payment.settingsForm.titleError"),message:e.$tc("payone-payment.settingsForm.messageTestError.general")}),e.isTesting=!1}))},getBind:function(e,t){var n;return t!==this.config&&(this.config=t),this.showValidationErrors&&("PayonePayment.settings.merchantId"!==e.name||this.merchantIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.accountId"!==e.name||this.accountIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.portalId"!==e.name||this.portalIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.portalKey"!==e.name||this.portalKeyFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")})),this.$refs.systemConfig.config.forEach((function(t){t.elements.forEach((function(t){t.name!==e.name||(n=t)}))})),n||e},getElementBind:function(e){var t=O.deepCopyObject(e);return null!==this.currentSalesChannelId&&this.inherit&&this.actualConfigData.hasOwnProperty("null")&&null!==this.actualConfigData.null[t.name]&&("single-select"===t.type||"sw-entity-single-select"===t.config.componentName?t.placeholder=this.$tc("sw-settings.system-config.inherited"):"bool"===t.type?t.config.inheritedValue=this.actualConfigData.null[t.name]||!1:"password"===t.type?(t.placeholderIsPassword=!0,t.placeholder="".concat(this.actualConfigData.null[t.name])):"multi-select"===t.type||x.isUndefined(this.actualConfigData.null[t.name])||(t.placeholder="".concat(this.actualConfigData.null[t.name]))),["single-select","multi-select"].includes(t.type)&&(t.config.labelProperty="name",t.config.valueProperty="id"),t}}});var I=n("ZzlF"),F=n.n(I),M=(n("KCDJ"),Shopware),N=M.Component,q=M.Mixin,$=Shopware.Data.Criteria;N.override("sw-order-detail-base",{template:F.a,inject:["PayonePaymentService","repositoryFactory","acl"],mixins:[q.getByName("notification")],data:function(){return{disableButtons:!1,notificationForwards:null}},computed:{payoneTransactions:function(){var e=this;return this.order.transactions.filter((function(t){return e.isPayoneTransaction(t)})).sort((function(e,t){return e.createdAtt.createdAt?-1:0}))},notificationForwardRepository:function(){return this.repositoryFactory.create("payone_payment_notification_forward")},notificationTargetColumns:function(){return[{property:"txaction",type:"text",width:"100px"},{property:"notificationTarget.url",type:"text"},{property:"response",width:"100px"},{property:"updatedAt",align:"right",type:"date"}]}},methods:{requeue:function(e,t){var n=this,i={notificationForwardId:e.id};this.PayonePaymentService.requeueNotificationForward(i).then((function(){n.createNotificationSuccess({title:n.$tc("payonePayment.notificationTarget.actions.requeue"),message:n.$tc("payonePayment.notificationTarget.messages.success")}),n.getNotificationForwards(t)})).catch((function(e){n.createNotificationError({title:n.$tc("payonePayment.notificationTarget.actions.requeue"),message:e.message})})).finally((function(){n.$nextTick().then((function(){n.$emit("reload")}))}))},isPayoneTransaction:function(e){return!!e.customFields&&e.customFields.payone_transaction_id},hasNotificationForwards:function(e){return null===this.notificationForwards?(this.getNotificationForwards(e),!1):!(this.notificationForwards.length<=0)},getNotificationForwards:function(e){var t=this,n=new $;return n.addAssociation("notificationTarget"),n.addSorting($.sort("updatedAt","DESC",!0)),n.addFilter($.equals("transactionId",e.id)),n.setLimit(500),this.notificationForwardRepository.search(n,Shopware.Context.api).then((function(e){t.notificationForwards=e}))},can:function(e){try{return this.acl.can(e)}catch(e){return!0}},isActiveTransaction:function(e){return"cancelled"!==e.stateMachineState.technicalName},hasPayoneTransaction:function(e){var t=this,n=!1;return!!e.transactions&&(e.transactions.map((function(e){t.isPayoneTransaction(e)&&t.isActiveTransaction(e)&&(n=!0)})),n)}}});var R=n("LmWz"),L=n.n(R),D=(n("HvTO"),Shopware.Component),B=Shopware.Context.app.config.version.match(/((\d+)\.?(\d+?)\.?(\d+)?\.?(\d*))-?([A-z]+?\d+)?/i);B&&6===parseInt(B[2])&&parseInt(B[3])<4&&D.override("sw-settings-index",{template:L.a});n("GGZ9");var j=n("IvS7"),Y=n("dyZK"),Z=Shopware.Module,z={type:"plugin",name:"PayonePayment",title:"payone-payment.general.mainMenuItemGeneral",description:"payone-payment.general.descriptionTextModule",version:"1.0.0",targetVersion:"1.0.0",icon:"default-action-settings",snippets:{"de-DE":j,"en-GB":Y},routeMiddleware:function(e,t){e(t)},routes:{index:{component:"payone-settings",path:"index",meta:{parentPath:"sw.settings.index"}}}},U=Shopware.Context.app.config.version.match(/((\d+)\.?(\d+?)\.?(\d+)?\.?(\d*))-?([A-z]+?\d+)?/i);U&&6===parseInt(U[2])&&parseInt(U[3])>3&&(z.settingsItem=[{name:"payone-payment",to:"payone.payment.index",label:"payone-payment.general.mainMenuItemGeneral",group:"plugins",iconComponent:"payone-payment-plugin-icon",backgroundEnabled:!1}]),Z.register("payone-payment",z);var G=n("XqXt"),V=n.n(G);function K(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function H(e){for(var t=1;t\n \n\n \n \n{% endblock %}\n'},XqXt:function(e,t){e.exports='{% block payone_notification_target_list %}\n \n\n {% block payone_notification_target_list_smart_bar_header %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_actions %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_content %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_sidebar %}\n \n {% endblock %}\n \n{% endblock %}\n'},ZS2F:function(e,t){e.exports='{% block payone_payment_payment_details %}\n
\n \n \n {{ $tc(\'payone-payment.refund.buttonTitle\') }}\n \n \n\n \n \n \n\n
\n \n \n \n \n \n \n
\n\n \n
\n
\n{% endblock %}\n'},ZzlF:function(e,t){e.exports='{% block sw_order_detail_delivery_metadata %}\n {% parent %}\n\n \n{% endblock %}\n'},bqMO:function(e,t){e.exports='{% block payone_payment_details %}\n
\n \n\n \n\n \n\n \n \n
\n{% endblock %}\n'},cm4w:function(e,t,n){},dyZK:function(e){e.exports=JSON.parse('{"payone-payment":{"title":"PAYONE","general":{"mainMenuItemGeneral":"PAYONE","descriptionTextModule":"Settings for PAYONE"},"capture":{"buttonTitle":"Capture","successTitle":"PAYONE","successMessage":"Capture processed successfully.","errorTitle":"PAYONE","errorMessage":"Capture could not be processed.","tooltips":{"impossible":"Capture impossible"}},"refund":{"buttonTitle":"Refund","successTitle":"PAYONE","successMessage":"Refund processed successfully.","errorTitle":"PAYONE","errorMessage":"Refund could not be processed.","tooltips":{"impossible":"Refund impossible"}},"modal":{"capture":{"title":"Capture","submit":"Capture","fullSubmit":"Full capture","amount":"Capture amount","captured":"Captured amount"},"refund":{"title":"Refund","submit":"Refund","fullSubmit":"Full Refund","amount":"Refund amount","refunded":"Refunded amount"},"orderAmount":"Order amount","remainingAmount":"Remaining amount","shippingCosts":"Shipping costs","descriptionHelpText":"Description help text","close":"Close","labelComment":"Label comment","columns":{"reference":"Reference","product":"Product","quantity":"Quantity","price":"Price"}},"settingsForm":{"save":"Save","test":"Test API Credentials","titleSuccess":"Success","titleError":"Error","labelShowSpecificStatusMapping":"Display state mapping configuration","helpTextShowSpecificStatusMapping":"If not configured the general status mapping config will be applied.","messageTestSuccess":"The API credentials were verified successfully.","messageTestNoTestedPayments":"No payment methods were tested during the check because none of the PAYONE payment methods are activated. Please activate at least one PAYONE payment method under Settings --\x3e Shop --\x3e Payment.","messageTestError":{"general":"The API credentials could not be verified successfully.","creditCard":"The API credentials for PAYONE Credit Card are not valid.","prepayment":"The API credentials for PAYONE Prepayment are not valid.","debit":"The API credentials for PAYONE Direct Debit are not valid.","paypalExpress":"The API credentials for PAYONE PayPal Express are not valid.","paypal":"The API credentials for PAYONE PayPal are not valid.","payolutionInstallment":"The API credentials for PAYONE Unzer Ratenkauf are not valid.","payolutionInvoicing":"The API credentials for PAYONE Unzer Rechnungskauf are not valid.","payolutionDebit":"The API credentials for PAYONE Unzer Lastschrift are not valid.","sofort":"The API credentials for PAYONE Sofort are not valid.","eps":"The API credentials for PAYONE eps are not valid.","iDeal":"The API credentials for PAYONE iDEAL are not valid.","secureInvoice":"The API credentials for PAYONE Secure Invoice are not valid.","openInvoice":"The API credentials for PAYONE Invoice are not valid.","paydirekt":"The API credentials for PAYONE paydirekt are not valid.","trustly":"The API credentials for PAYONE Trustly are not valid.","applePay":"The API credentials for PAYONE Apple Pay are not valid.","bancontact":"The API credentials for PAYONE Bancontact payment are not valid."}},"supportModal":{"menuButton":"Support","title":"How Can We Help You?","documentation":{"description":"Read our online manual","button":"Online Manual"},"support":{"description":"Contact our technical support","button":"Tech Support"},"repository":{"description":"Report errors on GitHub","button":"GitHub"},"testdata":{"description":"Create your personal test data here","button":"Test Data"}},"applePay":{"cert":{"notification":"The ApplePay merchant authentication requires a certificate/key-pair. Further information:
\\n https://docs.payone.com/display/public/PLATFORM/Special+Remarks+-+Apple+Pay#SpecialRemarks-ApplePay-Onboarding

\\n\\n Create a pem-File afterwards by using the following command:
\\n
openssl x509 -inform der -in merchant_id.cer -out merchant_id.pem

\\n Copy certificate (merchant_id.pem) and key (merchant_id.key) file into the following folder:
\\n
%shopwareRoot%/config/apple-pay-cert
"}},"transitionActionNames":{"cancel":"Cancel","complete":"Complete","pay":"Pay","pay_partially":"Pay partially","process":"Process","refund":"Refund","refund_partially":"Refund partially","remind":"Remind","reopen":"Reopen","retour":"Retour","retour_partially":"Retour partially","ship":"Ship","ship_partially":"Ship partially"},"messageNotBlank":"This field must not be empty.","txid":"TXID","sequenceNumber":{"label":"Sequence Number","empty":"none"},"transactionState":"State","transactionCancelled":"Transaction cancelled in Shopware","error":{"transaction":{"notFound":"No matching transaction could be found","orderNotFound":"No matching order could be found"}}},"sw-privileges":{"additional_permissions":{"Payone":{"label":"PAYONE","payone_order_management":"PAYONE transaction management"}}}}')},dzH1:function(e,t){e.exports='{% block payone_payment %}\n\n {% block payone_payment_header %}\n \n {% endblock %}\n\n {% block payone_payment_actions %}\n \n {% endblock %}\n\n {% block payone_payment_settings_content %}\n \n {% endblock %}\n\n{% endblock %}\n'},lkoS:function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:"payone";return i(this,l),c.call(this,e,t,n)}return t=l,(n=[{key:"requeueNotificationForward",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/requeue-forward");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}},{key:"capturePayment",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/capture-payment");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}},{key:"refundPayment",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/refund-payment");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}}])&&a(t.prototype,n),s&&a(t,s),Object.defineProperty(t,"prototype",{writable:!1}),l}(u);l.addServiceProvider("PayonePaymentService",(function(e){var t=l.getContainer("init");return new d(t.httpClient,e.loginService)}))},mJGU:function(e,t,n){var i=n("CPMY");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("66ab83f6",i,!0,{})},mOqv:function(e,t,n){var i=n("TAuu");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("88036906",i,!0,{})},mmGx:function(e){e.exports=JSON.parse('{"payonePayment":{"notificationTarget":{"module":{"title":"Payone Notificationweiterleitungen","buttonTitle":"Notifications"},"list":{"title":"Notificationweiterleitungen","empty":"Keine Einträge","buttonCreate":"Weiterleitungsziel anlegen"},"detail":{"headline":"Notificationweiterleitung","placeholder":{"url":"Url","username":"Benutzer","password":"Passwort"},"label":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions","buttonSave":"Speichern","buttonCancel":"Abbrechen","username":"Benutzer","password":"Passwort"}},"columns":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions"},"actions":{"requeue":"Erneut senden"},"messages":{"success":"Die Weiterleitung wurde erfolgreich in Auftrag gegeben."}}}}')},qSh7:function(e,t,n){},zyFP:function(e,t){e.exports='{% block payone_payment_plugin_icon %}\n \n{% endblock %}\n'}}); \ No newline at end of file +!function(e){var t={};function n(i){if(t[i])return t[i].exports;var a=t[i]={i:i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(i,a,function(t){return e[t]}.bind(null,a));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/bundles/payonepayment/",n(n.s="UZdK")}({"2O5J":function(e){e.exports=JSON.parse('{"payonePayment":{"notificationTarget":{"module":{"title":"Payone notification forward","buttonTitle":"Notifications"},"list":{"title":"Notification forward","empty":"No entries","buttonCreate":"Add new notification target"},"detail":{"headline":"Notification forward","placeholder":{"url":"Url","username":"Username","password":"Password"},"label":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions","buttonSave":"Save","buttonCancel":"Cancel","username":"Username","password":"Password"}},"columns":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions"},"actions":{"requeue":"Requeue"},"messages":{"success":"The notification forward has been successfully queued."}}}}')},"2f31":function(e,t){e.exports='{% block payone_notification_target_detail %}\n \n\n {% block payone_notification_target_detail_header %}\n \n {% endblock %}\n\n {% block payone_notification_target_detail_actions %}\n \n {% endblock %}\n\n {% block payone_notification_target_detail_content %}\n \n\n {% block payone_notification_target_detail_base_basic_info_card %}\n \n \n \n {% endblock %}\n \n {% endblock %}\n\n \n{% endblock %}\n'},"3U21":function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:"payone_payment";return i(this,l),c.call(this,e,t,n)}return t=l,(n=[{key:"validateApiCredentials",value:function(e){var t=this.getBasicHeaders();return this.httpClient.post("_action/".concat(this.getApiBasePath(),"/validate-api-credentials"),{credentials:e},{headers:t}).then((function(e){return u.handleResponse(e)}))}},{key:"getStateMachineTransitionActions",value:function(){var e=this.getBasicHeaders();return this.httpClient.get("_action/".concat(this.getApiBasePath(),"/get-state-machine-transition-actions"),{headers:e}).then((function(e){return u.handleResponse(e)}))}},{key:"hasApplePayCert",value:function(){var e=this.getBasicHeaders();return this.httpClient.get("_action/".concat(this.getApiBasePath(),"/check-apple-pay-cert"),{headers:e}).catch((function(){return!1})).then((function(e){return!!e}))}}])&&a(t.prototype,n),s&&a(t,s),Object.defineProperty(t,"prototype",{writable:!1}),l}(u);l.addServiceProvider("PayonePaymentSettingsService",(function(e){var t=l.getContainer("init");return new p(t.httpClient,e.loginService)}))},"3nqX":function(e,t,n){var i=n("K+0n");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("9e189240",i,!0,{})},"4GG1":function(e,t,n){var i=n("Gc8S");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("15e19ffa",i,!0,{})},"78OT":function(e,t){try{Shopware.Service("privileges").addPrivilegeMappingEntry({category:"additional_permissions",parent:null,key:"Payone",roles:{payone_order_management:{privileges:["order_transaction:update","order_line_item:update","state_machine_history:create",Shopware.Service("privileges").getPrivileges("order.viewer")],dependencies:[]}}})}catch(e){}},"8KF6":function(e,t,n){},"8aZc":function(e,t,n){},"9Sjd":function(e,t){e.exports='{% block payone_payment_payment_details %}\n
\n \n \n {{ $tc(\'payone-payment.capture.buttonTitle\') }}\n \n \n\n \n \n \n\n
\n \n \n \n \n \n \n
\n\n \n
\n
\n{% endblock %}\n'},CPMY:function(e,t,n){},DUF1:function(e,t,n){},FCfm:function(e,t,n){var i=n("qSh7");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("09344dd6",i,!0,{})},GGZ9:function(e,t){var n=Shopware.Filter,i=Shopware.Utils.format.currency;n.register("payone_currency",(function(e,t,n,a){return null===e?"-":(n||(n=0),e/=Math.pow(10,n),i(e,t,a))}))},Gc8S:function(e,t,n){},HvTO:function(e,t,n){var i=n("cm4w");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("d882c8f0",i,!0,{})},IvS7:function(e){e.exports=JSON.parse('{"payone-payment":{"title":"PAYONE","general":{"mainMenuItemGeneral":"PAYONE","descriptionTextModule":"Einstellungen für PAYONE","headlines":{"ratepayProfiles":"Profile","ratepayProfileConfigurations":"Profil-Konfigurationen"},"label":{"shopId":"Shop-ID","currency":"Währung","error":"Status","invoiceCountry":"Rechnungsland","shippingCountry":"Lieferland","minBasket":"Min. Warenkorb","maxBasket":"Max. Warenkorb","reloadConfigBtn":"Profil-Konfiguration neu laden","reloadConfigInfo":"(Änderungen an der Plugin-Konfiguration werden dabei zuerst gespeichert)"},"actions":{"addShop":"Shop-ID hinzufügen"},"errors":{"existingShopId":"Die eingegebene ShopId existiert bereits.","emptyInputs":"Bitte füllen Sie alle Eingabefelder aus."}},"capture":{"buttonTitle":"Capture","successTitle":"PAYONE","successMessage":"Capture erfolgreich durchgeführt.","errorTitle":"PAYONE","errorMessage":"Capture konnte nicht durchgeführt werden.","tooltips":{"impossible":"Einzug unmöglich"}},"refund":{"buttonTitle":"Refund","successTitle":"PAYONE","successMessage":"Refund erfolgreich durchgeführt.","errorTitle":"PAYONE","errorMessage":"Refund konnte nicht durchgeführt werden.","tooltips":{"impossible":"Erstattung unmöglich"}},"modal":{"capture":{"title":"Einzug","submit":"Einziehen","fullSubmit":"Alles Einziehen","amount":"Einzugswert","captured":"Eingezogener Wert"},"refund":{"title":"Erstattung","submit":"Erstatten","fullSubmit":"Alles Erstatten","amount":"Erstattungswert","refunded":"Erstatteter Wert"},"close":"Schließen","orderAmount":"Bestellungswert","remainingAmount":"Ausstehender Wert","shippingCosts":"Versandkosten","labelComment":"Label comment","descriptionHelpText":"Description help text","columns":{"reference":"Referenz","product":"Produkt","quantity":"Anzahl","price":"Preis"}},"settingsForm":{"save":"Speichern","test":"API-Zugangsdaten testen","titleSuccess":"Erfolg","titleError":"Fehler","labelShowSpecificStatusMapping":"Statusmappingkonfiguration einblenden","helpTextShowSpecificStatusMapping":"Sie können für jede Zahlungsart ein spezifisches Statusmapping konfigurieren. Existiert eine solche Konfiguration nicht, wird auf die allgemeine Konfiguration zurückgegriffen.","messageSaveError":{"ratepayProfilesUpdateFailed":"Mindestens ein Ratepay Profil konnte nicht erfolgreich gespeichert werden, bitte prüfen Sie Ihre Konfiguration."},"messageTestSuccess":"Die API-Zugangsdaten wurden erfolgreich validiert.","messageTestNoTestedPayments":"Bei der Prüfung wurden keine Zahlarten getestet, weil keine der PAYONE Zahlarten aktiviert ist. Bitte aktivieren Sie mindestens eine PAYONE Zahlart unter Einstellungen --\x3e Shop --\x3e Zahlungsarten.","messageTestError":{"general":"Die API-Zugangsdaten konnten nicht validiert werden.","creditCard":"Die API-Zugangsdaten für PAYONE Kreditkarte sind nicht korrekt.","prepayment":"Die API-Zugangsdaten für PAYONE Vorkasse sind nicht korrekt.","debit":"Die API-Zugangsdaten für PAYONE Lastschrift sind nicht korrekt.","paypalExpress":"Die API-Zugangsdaten für PAYONE PayPal Express sind nicht korrekt.","paypal":"Die API-Zugangsdaten für PAYONE PayPal sind nicht korrekt.","payolutionInstallment":"Die API-Zugangsdaten für PAYONE Unzer Ratenkauf sind nicht korrekt.","payolutionInvoicing":"Die API-Zugangsdaten für PAYONE Unzer Rechnungskauf sind nicht korrekt.","payolutionDebit":"Die API-Zugangsdaten für PAYONE Unzer Lastschrift sind nicht korrekt.","sofort":"Die API-Zugangsdaten für PAYONE Sofort Überweisung sind nicht korrekt.","eps":"Die API-Zugangsdaten für PAYONE eps Überweisung sind nicht korrekt.","iDeal":"Die API-Zugangsdaten für PAYONE iDEAL sind nicht korrekt.","secureInvoice":"Die API-Zugangsdaten für PAYONE Gesicherter Rechnungskauf sind nicht korrekt.","openInvoice":"Die API-Zugangsdaten für PAYONE Rechnungskauf sind nicht korrekt.","paydirekt":"Die API-Zugangsdaten für PAYONE paydirekt sind nicht korrekt.","trustly":"Die API-Zugangsdaten für PAYONE Trustly sind nicht korrekt.","applePay":"Die API-Zugangsdaten für PAYONE Apple Pay sind nicht korrekt.","bancontact":"Die API-Zugangsdaten für PAYONE Bancontact sind nicht korrekt.","ratepayDebit":"Die API-Zugangsdaten für PAYONE Ratepay Lastschrift sind nicht korrekt.","ratepayInstallment":"Die API-Zugangsdaten für PAYONE Ratepay Ratenzahlung sind nicht korrekt.","ratepayInvoicing":"Die API-Zugangsdaten für PAYONE Ratepay Rechnungskauf sind nicht korrekt."}},"supportModal":{"menuButton":"Support","title":"Wie können wir Ihnen helfen?","documentation":{"description":"Lesen Sie unsere Online-Dokumentation","button":"Dokumentation"},"support":{"description":"Kontaktieren Sie unseren Support","button":"Technischer Support"},"repository":{"description":"Melden Sie Fehler und Verbesserungen","button":"GitHub"},"testdata":{"description":"Erstellen Sie hier Ihre persönlichen Testdaten","button":"Testdaten"}},"applePay":{"cert":{"notification":"Für die Nutzung von ApplePay ist ein Zertifikat/Key-Paar zur Authentifizierung des Merchants erforderlich. Die Anlage eines solchen Zertifikats wird hier beschrieben:
\\n https://docs.payone.com/display/public/PLATFORM/Special+Remarks+-+Apple+Pay#SpecialRemarks-ApplePay-Onboarding

\\n\\n Erstellen Sie im Anschluss unter Verwendung des folgenden Befehls eine PEM-Datei des Zertifikates:
\\n
openssl x509 -inform der -in merchant_id.cer -out merchant_id.pem

\\n Hinterlegen Sie das Zertifikat (merchant_id.pem) und den Key (merchant_id.key) in folgendem Verzeichnis:
\\n
%shopwareRoot%/config/apple-pay-cert
"}},"transitionActionNames":{"cancel":"Stornieren","complete":"Abschließen","pay":"Bezahlen","pay_partially":"Teilweise bezahlen","process":"Durchführen","refund":"Rückerstatten","refund_partially":"Teilweise rückerstatten","remind":"Erinnern","reopen":"Wieder öffnen","retour":"Retoure","retour_partially":"Teilweise retounieren","ship":"Versenden","ship_partially":"Teilweise versenden"},"messageNotBlank":"Dieser Wert darf nicht leer sein.","txid":"TXID","sequenceNumber":{"label":"Sequenznummer","empty":"keine"},"transactionState":"Status","transactionCancelled":"Transaktion in Shopware abgebrochen","error":{"transaction":{"notFound":"Es wurde keine passende Transaktion gefundend","orderNotFound":"Es wurde keine passende Bestellung gefundend"}}},"sw-privileges":{"additional_permissions":{"Payone":{"label":"PAYONE","payone_order_management":"PAYONE Transaktionsmanagement"}}}}')},"K+0n":function(e,t,n){},KCDJ:function(e,t,n){var i=n("8KF6");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("74f42fc6",i,!0,{})},L3pH:function(e,t,n){var i=n("8aZc");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("c3ce2e1e",i,!0,{})},LmWz:function(e,t){e.exports='{% block sw_settings_content_card_slot_plugins %}\n {% parent %}\n\n \n \n \n{% endblock %}\n'},SZ7m:function(e,t,n){"use strict";function i(e,t){for(var n=[],i={},a=0;an.parts.length&&(i.parts.length=n.parts.length)}else{var r=[];for(a=0;a=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,r=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){s=!0,o=e},f:function(){try{r||null==n.return||n.return()}finally{if(s)throw o}}}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n0&&this.capturedAmount>0||this.transaction.customFields.payone_allow_capture)},isItemSelected:function(){var e=!1;return this.selection.forEach((function(t){t.selected&&(e=!0)})),e},hasRemainingShippingCosts:function(){var e=this;if(this.order.shippingCosts.totalPrice<=0)return!1;var t=this.order.shippingCosts.totalPrice*Math.pow(10,this.decimalPrecision),n=0;return this.order.lineItems.forEach((function(t){t.customFields&&t.customFields.payone_captured_quantity&&0=t)}},data:function(){return{isLoading:!1,hasError:!1,showCaptureModal:!1,isCaptureSuccessful:!1,selection:[],captureAmount:0,includeShippingCosts:!1}},methods:{calculateCaptureAmount:function(){var e=0;this.selection.forEach((function(t){t.selected&&(e+=t.unit_price*t.quantity)})),e>this.remainingAmount&&(e=this.remainingAmount),this.captureAmount=e},openCaptureModal:function(){this.showCaptureModal=!0,this.isCaptureSuccessful=!1,this.selection=[]},closeCaptureModal:function(){this.showCaptureModal=!1},onCaptureFinished:function(){this.isCaptureSuccessful=!1},captureOrder:function(){var e=this,t={orderTransactionId:this.transaction.id,payone_order_id:this.transaction.customFields.payone_transaction_id,salesChannel:this.order.salesChannel,amount:this.captureAmount,orderLines:[],complete:this.captureAmount===this.remainingAmount,includeShippingCosts:!1};this.isLoading=!0,this.selection.forEach((function(n){e.order.lineItems.forEach((function(e){if(e.id===n.id&&n.selected&&00&&this.selection.push({id:"shipping",quantity:1,unit_price:this.order.shippingCosts.totalPrice,selected:!1})}}});var _=n("ZS2F"),v=n.n(_);n("mJGU");function w(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function P(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S=Shopware,k=S.Component,C=S.Mixin;k.register("payone-refund-button",{template:v.a,mixins:[C.getByName("notification")],inject:["PayonePaymentService"],props:{order:{type:Object,required:!0},transaction:{type:Object,required:!0}},data:function(){return{isLoading:!1,hasError:!1,showRefundModal:!1,isRefundSuccessful:!1,selection:[],refundAmount:0,includeShippingCosts:!1}},computed:{decimalPrecision:function(){return this.order&&this.order.currency?this.order.currency.decimalPrecision?this.order.currency.decimalPrecision:this.order.currency.itemRounding?this.order.currency.itemRounding.decimals:void 0:2},remainingAmount:function(){return void 0===this.transaction.customFields||void 0===this.transaction.customFields.payone_captured_amount?0:this.transaction.customFields.payone_captured_amount-this.refundedAmount},refundedAmount:function(){return void 0===this.transaction.customFields||void 0===this.transaction.customFields.payone_refunded_amount?0:this.transaction.customFields.payone_refunded_amount},maxRefundAmount:function(){return this.remainingAmount/Math.pow(10,this.decimalPrecision)},buttonEnabled:function(){return!!this.transaction.customFields&&(this.remainingAmount>0&&this.refundedAmount>0||this.transaction.customFields.payone_allow_refund)},hasRemainingRefundableShippingCosts:function(){var e=this;if(this.order.shippingCosts.totalPrice<=0)return!1;var t=this.order.shippingCosts.totalPrice*Math.pow(10,this.decimalPrecision),n=0;return this.order.lineItems.forEach((function(t){t.customFields&&t.customFields.payone_refunded_quantity&&0=t)}},methods:{calculateRefundAmount:function(){var e=0;this.selection.forEach((function(t){t.selected&&(e+=t.unit_price*t.quantity)})),Math.round(e*Math.pow(10,this.decimalPrecision)>this.remainingAmount)&&(e=this.remainingAmount/Math.pow(10,this.decimalPrecision)),this.refundAmount=e},openRefundModal:function(){this.showRefundModal=!0,this.isRefundSuccessful=!1,this.selection=[]},closeRefundModal:function(){this.showRefundModal=!1},onRefundFinished:function(){this.isRefundSuccessful=!1},refundOrder:function(){var e=this,t={orderTransactionId:this.transaction.id,payone_order_id:this.transaction.customFields.payone_transaction_id,salesChannel:this.order.salesChannel,amount:this.refundAmount,orderLines:[],complete:this.refundAmount===this.maxRefundAmount,includeShippingCosts:!1};this.isLoading=!0,this.selection.forEach((function(n){e.order.lineItems.forEach((function(i){if(i.id===n.id&&n.selected&&00&&this.selection.push({id:"shipping",quantity:1,unit_price:this.order.shippingCosts.totalPrice,selected:!1})}}});var A=n("bqMO"),I=n.n(A);n("4GG1");Shopware.Component.register("payone-order-items",{template:I.a,props:{order:{type:Object,required:!0},mode:{type:String,required:!1}},computed:{orderItems:function(){var e=this,t=[];return this.order.lineItems.forEach((function(n){var i=e.$options.filters.currency(n.totalPrice,e.order.currency.shortName,e.order.decimal_precision),a=!1,o=n.quantity;n.customFields&&("refund"===e.mode?(n.customFields.payone_captured_quantity&&0>n.customFields.payone_captured_quantity&&(o=n.customFields.payone_captured_quantity),n.customFields.payone_refunded_quantity&&(o-=n.customFields.payone_refunded_quantity)):"capture"===e.mode&&n.customFields.payone_captured_quantity&&0o&&(a=!0),t.push({id:n.id,product:n.label,quantity:o,disabled:a,selected:!1,price:i,orderItem:n})})),this.order.shippingCosts.totalPrice>0&&t.push({id:"shipping",product:this.$tc("payone-payment.modal.shippingCosts"),quantity:1,disabled:!1,selected:!1,price:this.$options.filters.currency(this.order.shippingCosts.totalPrice,this.order.currency.shortName,this.order.decimal_precision),orderItem:{}}),t},orderItemColumns:function(){return[{property:"product",label:this.$tc("payone-payment.modal.columns.product"),rawData:!0},{property:"quantity",label:this.$tc("payone-payment.modal.columns.quantity"),rawData:!0},{property:"price",label:this.$tc("payone-payment.modal.columns.price"),rawData:!0}]}},methods:{onSelectItem:function(e,t,n){this.$emit("select-item",t.id,n)},onChangeQuantity:function(e,t){this.$emit("change-quantity",t,e)}}});var T=n("Vxi/"),E=n.n(T);Shopware.Component.extend("payone-data-grid","sw-data-grid",{template:E.a});var x=n("zyFP"),O=n.n(x);n("3nqX");Shopware.Component.register("payone-payment-plugin-icon",{template:O.a});var $=n("dzH1"),F=n.n($),M=(n("mOqv"),Shopware),N=M.Component,R=M.Mixin,q=Shopware.Utils,D=q.object,L=q.types;N.register("payone-settings",{template:F.a,mixins:[R.getByName("notification"),R.getByName("sw-inline-snippet")],inject:["PayonePaymentSettingsService"],data:function(){return{isLoading:!1,isTesting:!1,isSaveSuccessful:!1,isTestSuccessful:!1,isApplePayCertConfigured:!0,config:{},merchantIdFilled:!1,accountIdFilled:!1,portalIdFilled:!1,portalKeyFilled:!1,showValidationErrors:!1,isSupportModalOpen:!1,stateMachineTransitionActions:[],displayStatusMapping:{},collapsibleState:{status_mapping:!0,payment_credit_card:!0,payment_paypal:!0,payment_paypal_express:!0,payment_debit:!0,payment_sofort:!0,payment_payolution_installment:!0,payment_payolution_invoicing:!0,payment_payolution_debit:!0,payment_eps:!0,payment_ideal:!0,payment_paydirekt:!0,payment_prepayment:!0,payment_trustly:!0,payment_secure_invoice:!0,payment_open_invoice:!0,payment_apple_pay:!0,payment_bancontact:!0,payment_ratepay_debit:!0,payment_ratepay_installment:!0,payment_ratepay_invoicing:!0}}},created:function(){this.createdComponent()},computed:{credentialsMissing:function(){return!(this.merchantIdFilled&&this.accountIdFilled&&this.portalIdFilled&&this.portalKeyFilled)}},metaInfo:function(){return{title:this.$createTitle()}},methods:{createdComponent:function(){var e=this,t=this;this.PayonePaymentSettingsService.getStateMachineTransitionActions().then((function(e){e.data.forEach((function(e){var n="payone-payment.transitionActionNames."+e.label,i=t.$t(n);i===n&&(i=e.label),t.stateMachineTransitionActions.push({label:i,value:e.value})}))})),this.PayonePaymentSettingsService.hasApplePayCert().then((function(t){e.isApplePayCertConfigured=t}))},paymentMethodPrefixes:function(){return["creditCard","debit","paypal","paypalExpress","payolutionInvoicing","payolutionInstallment","payolutionDebit","sofort","eps","iDeal","paydirekt","prepayment","trustly","secureInvoice","openInvoice","applePay","bancontact","ratepayDebit","ratepayInstallment","ratepayInvoicing"]},isVisiblePaymentMethodCard:function(e){return e.name.startsWith("payment")&&!this.isCollapsed(e)},isCollapsible:function(e){return e.name in this.collapsibleState},displayField:function(e,t,n){return!(n.name in this.collapsibleState)||!this.collapsibleState[n.name]},isCollapsed:function(e){return this.collapsibleState[e.name]},toggleCollapsible:function(e){e.name in this.collapsibleState&&(this.collapsibleState[e.name]=!this.collapsibleState[e.name])},saveFinish:function(){this.isSaveSuccessful=!1},testFinish:function(){this.isTestSuccessful=!1},onConfigChange:function(e){this.config=e,this.checkCredentialsFilled(),this.showValidationErrors=!1},checkCredentialsFilled:function(){this.merchantIdFilled=!!this.getConfigValue("merchantId"),this.accountIdFilled=!!this.getConfigValue("accountId"),this.portalIdFilled=!!this.getConfigValue("portalId"),this.portalKeyFilled=!!this.getConfigValue("portalKey")},getConfigValue:function(e){var t=this.$refs.systemConfig.actualConfigData.null;return null===this.$refs.systemConfig.currentSalesChannelId?this.config["PayonePayment.settings.".concat(e)]:this.config["PayonePayment.settings.".concat(e)]||t["PayonePayment.settings.".concat(e)]},getPaymentConfigValue:function(e,t){var n=e.charAt(0).toUpperCase()+e.slice(1);return this.getConfigValue(t+n)||this.getConfigValue(e)},onSave:function(){var e=this;this.credentialsMissing?this.showValidationErrors=!0:(this.isSaveSuccessful=!1,this.isLoading=!0,this.$refs.systemConfig.saveAll().then((function(t){e.handleRatepayProfileUpdates(t),e.isLoading=!1,e.isSaveSuccessful=!0})).catch((function(){e.isLoading=!1})))},onTest:function(){var e=this;this.isTesting=!0,this.isTestSuccessful=!1;var t={};this.paymentMethodPrefixes().forEach((function(n){t[n]={merchantId:e.getPaymentConfigValue("merchantId",n),accountId:e.getPaymentConfigValue("accountId",n),portalId:e.getPaymentConfigValue("portalId",n),portalKey:e.getPaymentConfigValue("portalKey",n)}})),this.PayonePaymentSettingsService.validateApiCredentials(t).then((function(t){var n=t.testCount,i=t.credentialsValid,a=t.errors;if(i)e.createNotificationSuccess({title:e.$tc("payone-payment.settingsForm.titleSuccess"),message:n>0?e.$tc("payone-payment.settingsForm.messageTestSuccess"):e.$tc("payone-payment.settingsForm.messageTestNoTestedPayments")}),e.isTestSuccessful=!0;else for(var o in a)a.hasOwnProperty(o)&&e.createNotificationError({title:e.$tc("payone-payment.settingsForm.titleError"),message:e.$tc("payone-payment.settingsForm.messageTestError."+o)});e.isTesting=!1})).catch((function(t){e.createNotificationError({title:e.$tc("payone-payment.settingsForm.titleError"),message:e.$tc("payone-payment.settingsForm.messageTestError.general")}),e.isTesting=!1}))},getBind:function(e,t){var n;return t!==this.config&&(this.config=t),this.showValidationErrors&&("PayonePayment.settings.merchantId"!==e.name||this.merchantIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.accountId"!==e.name||this.accountIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.portalId"!==e.name||this.portalIdFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")}),"PayonePayment.settings.portalKey"!==e.name||this.portalKeyFilled||(e.config.error={code:1,detail:this.$tc("payone-payment.messageNotBlank")})),this.$refs.systemConfig.config.forEach((function(t){t.elements.forEach((function(t){t.name!==e.name||(n=t)}))})),n||e},getElementBind:function(e){var t=D.deepCopyObject(e);return null!==this.currentSalesChannelId&&this.inherit&&this.actualConfigData.hasOwnProperty("null")&&null!==this.actualConfigData.null[t.name]&&("single-select"===t.type||"sw-entity-single-select"===t.config.componentName?t.placeholder=this.$tc("sw-settings.system-config.inherited"):"bool"===t.type?t.config.inheritedValue=this.actualConfigData.null[t.name]||!1:"password"===t.type?(t.placeholderIsPassword=!0,t.placeholder="".concat(this.actualConfigData.null[t.name])):"multi-select"===t.type||L.isUndefined(this.actualConfigData.null[t.name])||(t.placeholder="".concat(this.actualConfigData.null[t.name]))),["single-select","multi-select"].includes(t.type)&&(t.config.labelProperty="name",t.config.valueProperty="id"),t},handleRatepayProfileUpdates:function(e){var t=this.$refs.systemConfig.currentSalesChannelId;if(e.payoneRatepayProfilesUpdateResult&&e.payoneRatepayProfilesUpdateResult[t]){var n=e.payoneRatepayProfilesUpdateResult[t];this.$root.$emit("payone-ratepay-profiles-update-result",n),Array.isArray(n.errors)||this.createNotificationError({title:this.$tc("payone-payment.settingsForm.titleError"),message:this.$tc("payone-payment.settingsForm.messageSaveError.ratepayProfilesUpdateFailed")})}}}});var B=n("ZzlF"),j=n.n(B),Y=(n("KCDJ"),Shopware),Z=Y.Component,z=Y.Mixin,U=Shopware.Data.Criteria;Z.override("sw-order-detail-base",{template:j.a,inject:["PayonePaymentService","repositoryFactory","acl"],mixins:[z.getByName("notification")],data:function(){return{disableButtons:!1,notificationForwards:null}},computed:{payoneTransactions:function(){var e=this;return this.order.transactions.filter((function(t){return e.isPayoneTransaction(t)})).sort((function(e,t){return e.createdAtt.createdAt?-1:0}))},notificationForwardRepository:function(){return this.repositoryFactory.create("payone_payment_notification_forward")},notificationTargetColumns:function(){return[{property:"txaction",type:"text",width:"100px"},{property:"notificationTarget.url",type:"text"},{property:"response",width:"100px"},{property:"updatedAt",align:"right",type:"date"}]}},methods:{requeue:function(e,t){var n=this,i={notificationForwardId:e.id};this.PayonePaymentService.requeueNotificationForward(i).then((function(){n.createNotificationSuccess({title:n.$tc("payonePayment.notificationTarget.actions.requeue"),message:n.$tc("payonePayment.notificationTarget.messages.success")}),n.getNotificationForwards(t)})).catch((function(e){n.createNotificationError({title:n.$tc("payonePayment.notificationTarget.actions.requeue"),message:e.message})})).finally((function(){n.$nextTick().then((function(){n.$emit("reload")}))}))},isPayoneTransaction:function(e){return!!e.customFields&&e.customFields.payone_transaction_id},hasNotificationForwards:function(e){return null===this.notificationForwards?(this.getNotificationForwards(e),!1):!(this.notificationForwards.length<=0)},getNotificationForwards:function(e){var t=this,n=new U;return n.addAssociation("notificationTarget"),n.addSorting(U.sort("updatedAt","DESC",!0)),n.addFilter(U.equals("transactionId",e.id)),n.setLimit(500),this.notificationForwardRepository.search(n,Shopware.Context.api).then((function(e){t.notificationForwards=e}))},can:function(e){try{return this.acl.can(e)}catch(e){return!0}},isActiveTransaction:function(e){return"cancelled"!==e.stateMachineState.technicalName},hasPayoneTransaction:function(e){var t=this,n=!1;return!!e.transactions&&(e.transactions.map((function(e){t.isPayoneTransaction(e)&&t.isActiveTransaction(e)&&(n=!0)})),n)}}});var G=n("LmWz"),K=n.n(G),V=(n("HvTO"),Shopware.Component),H=Shopware.Context.app.config.version.match(/((\d+)\.?(\d+?)\.?(\d+)?\.?(\d*))-?([A-z]+?\d+)?/i);H&&6===parseInt(H[2])&&parseInt(H[3])<4&&V.override("sw-settings-index",{template:K.a});n("GGZ9");var W=n("IvS7"),J=n("dyZK"),X=Shopware.Module,Q={type:"plugin",name:"PayonePayment",title:"payone-payment.general.mainMenuItemGeneral",description:"payone-payment.general.descriptionTextModule",version:"1.0.0",targetVersion:"1.0.0",icon:"default-action-settings",snippets:{"de-DE":W,"en-GB":J},routeMiddleware:function(e,t){e(t)},routes:{index:{component:"payone-settings",path:"index",meta:{parentPath:"sw.settings.index"}}}},ee=Shopware.Context.app.config.version.match(/((\d+)\.?(\d+?)\.?(\d+)?\.?(\d*))-?([A-z]+?\d+)?/i);ee&&6===parseInt(ee[2])&&parseInt(ee[3])>3&&(Q.settingsItem=[{name:"payone-payment",to:"payone.payment.index",label:"payone-payment.general.mainMenuItemGeneral",group:"plugins",iconComponent:"payone-payment-plugin-icon",backgroundEnabled:!1}]),X.register("payone-payment",Q);var te=n("XqXt"),ne=n.n(te);function ie(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function ae(e){for(var t=1;t\n \n\n \n \n{% endblock %}\n'},XqXt:function(e,t){e.exports='{% block payone_notification_target_list %}\n \n\n {% block payone_notification_target_list_smart_bar_header %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_actions %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_content %}\n \n {% endblock %}\n\n {% block payone_notification_target_list_sidebar %}\n \n {% endblock %}\n \n{% endblock %}\n'},ZS2F:function(e,t){e.exports='{% block payone_payment_payment_details %}\n
\n \n \n {{ $tc(\'payone-payment.refund.buttonTitle\') }}\n \n \n\n \n \n \n\n
\n \n \n \n \n \n \n
\n\n \n
\n
\n{% endblock %}\n'},ZzlF:function(e,t){e.exports='{% block sw_order_detail_delivery_metadata %}\n {% parent %}\n\n \n{% endblock %}\n'},bqMO:function(e,t){e.exports='{% block payone_payment_details %}\n
\n \n\n \n\n \n\n \n \n
\n{% endblock %}\n'},cm4w:function(e,t,n){},dyZK:function(e){e.exports=JSON.parse('{"payone-payment":{"title":"PAYONE","general":{"mainMenuItemGeneral":"PAYONE","descriptionTextModule":"Settings for PAYONE","headlines":{"ratepayProfiles":"Profile","ratepayProfileConfigurations":"Profil-Konfigurationen"},"label":{"shopId":"Shop-ID","currency":"Currency","error":"Status","invoiceCountry":"Invoice Country","shippingCountry":"Shipping Country","minBasket":"Min. Basket","maxBasket":"Max. Basket","reloadConfigBtn":"Reload Profile Configuration","reloadConfigInfo":"(Plugin Configuration Changes will be saved first)"},"actions":{"addShop":"Add Shop-ID"},"errors":{"existingShopId":"The entered shop-id already exists.","emptyInputs":"Please fill all input fields."}},"capture":{"buttonTitle":"Capture","successTitle":"PAYONE","successMessage":"Capture processed successfully.","errorTitle":"PAYONE","errorMessage":"Capture could not be processed.","tooltips":{"impossible":"Capture impossible"}},"refund":{"buttonTitle":"Refund","successTitle":"PAYONE","successMessage":"Refund processed successfully.","errorTitle":"PAYONE","errorMessage":"Refund could not be processed.","tooltips":{"impossible":"Refund impossible"}},"modal":{"capture":{"title":"Capture","submit":"Capture","fullSubmit":"Full capture","amount":"Capture amount","captured":"Captured amount"},"refund":{"title":"Refund","submit":"Refund","fullSubmit":"Full Refund","amount":"Refund amount","refunded":"Refunded amount"},"orderAmount":"Order amount","remainingAmount":"Remaining amount","shippingCosts":"Shipping costs","descriptionHelpText":"Description help text","close":"Close","labelComment":"Label comment","columns":{"reference":"Reference","product":"Product","quantity":"Quantity","price":"Price"}},"settingsForm":{"save":"Save","test":"Test API Credentials","titleSuccess":"Success","titleError":"Error","labelShowSpecificStatusMapping":"Display state mapping configuration","helpTextShowSpecificStatusMapping":"If not configured the general status mapping config will be applied.","messageSaveError":{"ratepayProfilesUpdateFailed":"At least one Ratepay profile could not be saved successfully, please check your configuration."},"messageTestSuccess":"The API credentials were verified successfully.","messageTestNoTestedPayments":"No payment methods were tested during the check because none of the PAYONE payment methods are activated. Please activate at least one PAYONE payment method under Settings --\x3e Shop --\x3e Payment.","messageTestError":{"general":"The API credentials could not be verified successfully.","creditCard":"The API credentials for PAYONE Credit Card are not valid.","prepayment":"The API credentials for PAYONE Prepayment are not valid.","debit":"The API credentials for PAYONE Direct Debit are not valid.","paypalExpress":"The API credentials for PAYONE PayPal Express are not valid.","paypal":"The API credentials for PAYONE PayPal are not valid.","payolutionInstallment":"The API credentials for PAYONE Unzer Ratenkauf are not valid.","payolutionInvoicing":"The API credentials for PAYONE Unzer Rechnungskauf are not valid.","payolutionDebit":"The API credentials for PAYONE Unzer Lastschrift are not valid.","sofort":"The API credentials for PAYONE Sofort are not valid.","eps":"The API credentials for PAYONE eps are not valid.","iDeal":"The API credentials for PAYONE iDEAL are not valid.","secureInvoice":"The API credentials for PAYONE Secure Invoice are not valid.","openInvoice":"The API credentials for PAYONE Invoice are not valid.","paydirekt":"The API credentials for PAYONE paydirekt are not valid.","trustly":"The API credentials for PAYONE Trustly are not valid.","applePay":"The API credentials for PAYONE Apple Pay are not valid.","bancontact":"The API credentials for PAYONE Bancontact payment are not valid.","ratepayDebit":"The API credentials for PAYONE Ratepay Direct Debit payment are not valid.","ratepayInstallment":"The API credentials for PAYONE Ratepay Installments payment are not valid.","ratepayInvoicing":"The API credentials for PAYONE Ratepay Open Invoice payment are not valid."}},"supportModal":{"menuButton":"Support","title":"How Can We Help You?","documentation":{"description":"Read our online manual","button":"Online Manual"},"support":{"description":"Contact our technical support","button":"Tech Support"},"repository":{"description":"Report errors on GitHub","button":"GitHub"},"testdata":{"description":"Create your personal test data here","button":"Test Data"}},"applePay":{"cert":{"notification":"The ApplePay merchant authentication requires a certificate/key-pair. Further information:
\\n https://docs.payone.com/display/public/PLATFORM/Special+Remarks+-+Apple+Pay#SpecialRemarks-ApplePay-Onboarding

\\n\\n Create a pem-File afterwards by using the following command:
\\n
openssl x509 -inform der -in merchant_id.cer -out merchant_id.pem

\\n Copy certificate (merchant_id.pem) and key (merchant_id.key) file into the following folder:
\\n
%shopwareRoot%/config/apple-pay-cert
"}},"transitionActionNames":{"cancel":"Cancel","complete":"Complete","pay":"Pay","pay_partially":"Pay partially","process":"Process","refund":"Refund","refund_partially":"Refund partially","remind":"Remind","reopen":"Reopen","retour":"Retour","retour_partially":"Retour partially","ship":"Ship","ship_partially":"Ship partially"},"messageNotBlank":"This field must not be empty.","txid":"TXID","sequenceNumber":{"label":"Sequence Number","empty":"none"},"transactionState":"State","transactionCancelled":"Transaction cancelled in Shopware","error":{"transaction":{"notFound":"No matching transaction could be found","orderNotFound":"No matching order could be found"}}},"sw-privileges":{"additional_permissions":{"Payone":{"label":"PAYONE","payone_order_management":"PAYONE transaction management"}}}}')},dzH1:function(e,t){e.exports='{% block payone_payment %}\n\n {% block payone_payment_header %}\n \n {% endblock %}\n\n {% block payone_payment_actions %}\n \n {% endblock %}\n\n {% block payone_payment_settings_content %}\n \n {% endblock %}\n\n{% endblock %}\n'},gyOs:function(e,t){e.exports='{% block payone_ratepay_profiles %}\n
\n {% block payone_ratepay_shop_ids %}\n

{{ $tc(\'payone-payment.general.headlines.ratepayProfiles\') }}

\n \n\n {% block payone_ratepay_shop_ids_actions %}\n \n\n {% block payone_ratepay_shop_ids_create_actions %}\n
\n \n {{ $tc(\'payone-payment.general.actions.addShop\') }}\n \n
\n {% endblock %}\n
\n {% endblock %}\n\n {% block payone_ratepay_shop_ids_grid %}\n \n {% block payone_ratepay_shop_ids_grid_columns %}\n {% block payone_ratepay_shop_ids_grid_column_status %}\n \n {% endblock %}\n\n {% block payone_ratepay_shop_ids_bulk_actions %}\n \n {% endblock %}\n {% endblock %}\n \n {% endblock %}\n\n {% block payone_ratepay_shop_ids_error %}\n \n {{ $tc(\'payone-payment.general.errors.existingShopId\') }}\n \n\n \n {{ $tc(\'payone-payment.general.errors.emptyInputs\') }}\n \n {% endblock %}\n
\n {% endblock %}\n
\n{% endblock %}\n'},lkoS:function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:"payone";return i(this,l),c.call(this,e,t,n)}return t=l,(n=[{key:"requeueNotificationForward",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/requeue-forward");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}},{key:"capturePayment",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/capture-payment");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}},{key:"refundPayment",value:function(e){var t="_action/".concat(this.getApiBasePath(),"/refund-payment");return this.httpClient.post(t,e,{headers:this.getBasicHeaders()}).then((function(e){return u.handleResponse(e)}))}}])&&a(t.prototype,n),s&&a(t,s),Object.defineProperty(t,"prototype",{writable:!1}),l}(u);l.addServiceProvider("PayonePaymentService",(function(e){var t=l.getContainer("init");return new p(t.httpClient,e.loginService)}))},mJGU:function(e,t,n){var i=n("CPMY");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("66ab83f6",i,!0,{})},mOqv:function(e,t,n){var i=n("TAuu");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("88036906",i,!0,{})},mmGx:function(e){e.exports=JSON.parse('{"payonePayment":{"notificationTarget":{"module":{"title":"Payone Notificationweiterleitungen","buttonTitle":"Notifications"},"list":{"title":"Notificationweiterleitungen","empty":"Keine Einträge","buttonCreate":"Weiterleitungsziel anlegen"},"detail":{"headline":"Notificationweiterleitung","placeholder":{"url":"Url","username":"Benutzer","password":"Passwort"},"label":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions","buttonSave":"Speichern","buttonCancel":"Abbrechen","username":"Benutzer","password":"Passwort"}},"columns":{"url":"Url","isBasicAuth":"Basic Auth","txactions":"txactions"},"actions":{"requeue":"Erneut senden"},"messages":{"success":"Die Weiterleitung wurde erfolgreich in Auftrag gegeben."}}}}')},nXgq:function(e,t){e.exports="{% block payone_ratepay_profile_configurations %}\n
\n

{{ $tc('payone-payment.general.headlines.ratepayProfileConfigurations') }}

\n\n \n
\n{% endblock %}\n"},qSh7:function(e,t,n){},stah:function(e,t,n){var i=n("DUF1");i.__esModule&&(i=i.default),"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);(0,n("SZ7m").default)("412bd730",i,!0,{})},zyFP:function(e,t){e.exports='{% block payone_payment_plugin_icon %}\n \n{% endblock %}\n'}}); \ No newline at end of file diff --git a/src/Resources/public/administration/js/payone-payment.js.map b/src/Resources/public/administration/js/payone-payment.js.map index 415c1712e..cc88efaf6 100644 --- a/src/Resources/public/administration/js/payone-payment.js.map +++ b/src/Resources/public/administration/js/payone-payment.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-notification-target/page/payone-notification-target-detail/payone-notification-target-detail.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/api/payone-payment-settings.service.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/payone-payment-plugin-icon/payone-payment-plugin-icon.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/order-items/order-items.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/acl/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/capture/capture.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/capture/style.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/filter/payone_currency.filter.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-settings-index/sw-settings-index.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-order/sw-order.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-settings-index/sw-settings-index.html.twig","webpack:///./node_modules/vue-style-loader/lib/listToStyles.js","webpack:///./node_modules/vue-style-loader/lib/addStylesClient.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/capture/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/refund/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/order-items/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/payone-data-grid/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/payone-payment-plugin-icon/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-order/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-settings-index/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-notification-target/page/payone-notification-target-list/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-notification-target/page/payone-notification-target-detail/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-notification-target/index.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/payone-data-grid/payone-data-grid.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-notification-target/page/payone-notification-target-list/payone-notification-target-list.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/refund/refund.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/extension/sw-order/sw-order.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/order-items/order-items.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/payone-settings.html.twig","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/api/payone-payment.service.js","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/refund/style.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/page/payone-settings/style.scss","webpack:////var/www/html/_github/PayonePayment/src/Resources/app/administration/src/module/payone-payment/component/payone-payment-plugin-icon/payone-payment-plugin-icon.html.twig"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","Application","Shopware","ApiService","Classes","PayonePaymentSettingsService","httpClient","loginService","apiEndpoint","credentials","headers","this","getBasicHeaders","post","getApiBasePath","then","response","handleResponse","catch","addServiceProvider","container","initContainer","getContainer","content","locals","add","default","Service","addPrivilegeMappingEntry","category","parent","roles","payone_order_management","privileges","getPrivileges","dependencies","e","Filter","currency","Utils","format","register","decimalPrecision","decimalPlaces","listToStyles","parentId","list","styles","newStyles","length","item","id","part","css","media","sourceMap","parts","push","hasDocument","document","DEBUG","Error","stylesInDom","head","getElementsByTagName","singletonElement","singletonCounter","isProduction","noop","options","ssrIdKey","isOldIE","navigator","test","userAgent","toLowerCase","addStylesClient","_isProduction","_options","addStylesToDom","newList","mayRemove","domStyle","refs","j","addStyle","createStyleElement","styleElement","createElement","type","appendChild","obj","update","remove","querySelector","parentNode","removeChild","styleIndex","applyToSingletonTag","applyToTag","newObj","textStore","replaceText","index","replacement","filter","Boolean","join","styleSheet","cssText","cssNode","createTextNode","childNodes","insertBefore","setAttribute","ssrId","sources","btoa","unescape","encodeURIComponent","JSON","stringify","firstChild","Component","Mixin","Context","template","mixins","getByName","inject","props","order","required","transaction","computed","itemRounding","decimals","totalTransactionAmount","Math","round","amount","totalPrice","capturedAmount","customFields","undefined","payone_captured_amount","remainingAmount","maxCaptureAmount","buttonEnabled","payone_allow_capture","isItemSelected","returnValue","selection","forEach","selected","hasRemainingShippingCosts","shippingCosts","capturedPositionAmount","lineItems","order_item","payone_captured_quantity","unitPrice","data","isLoading","hasError","showCaptureModal","isCaptureSuccessful","captureAmount","includeShippingCosts","methods","calculateCaptureAmount","unit_price","quantity","openCaptureModal","closeCaptureModal","onCaptureFinished","captureOrder","request","orderTransactionId","payone_order_id","payone_transaction_id","salesChannel","orderLines","complete","copy","taxRate","tax_rate","total_amount","total_tax_amount","executeCapture","captureFullOrder","PayonePaymentService","capturePayment","createNotificationSuccess","title","$tc","message","error","createNotificationError","finally","$nextTick","$emit","onSelectItem","_populateSelectionProperty","onChangeQuantity","showRefundModal","isRefundSuccessful","refundAmount","refundedAmount","payone_refunded_amount","maxRefundAmount","payone_allow_refund","hasRemainingRefundableShippingCosts","refundedPositionAmount","payone_refunded_quantity","calculateRefundAmount","openRefundModal","closeRefundModal","onRefundFinished","refundOrder","refundPayment","refundFullOrder","String","orderItems","price","$options","filters","shortName","decimal_precision","disabled","product","label","orderItem","orderItemColumns","rawData","extend","types","isTesting","isSaveSuccessful","isTestSuccessful","isApplePayCertConfigured","config","merchantIdFilled","accountIdFilled","portalIdFilled","portalKeyFilled","showValidationErrors","isSupportModalOpen","stateMachineTransitionActions","displayStatusMapping","collapsibleState","created","createdComponent","credentialsMissing","metaInfo","$createTitle","me","getStateMachineTransitionActions","result","element","translationKey","translationValue","$t","hasApplePayCert","paymentMethodPrefixes","isVisiblePaymentMethodCard","card","startsWith","isCollapsed","isCollapsible","displayField","toggleCollapsible","saveFinish","testFinish","onConfigChange","checkCredentialsFilled","getConfigValue","field","defaultConfig","$refs","systemConfig","actualConfigData","null","currentSalesChannelId","getPaymentConfigValue","prefix","uppercasedField","charAt","toUpperCase","slice","onSave","saveAll","onTest","merchantId","accountId","portalId","portalKey","validateApiCredentials","testCount","credentialsValid","errors","errorResponse","getBind","originalElement","code","detail","configElement","elements","child","getElementBind","deepCopyObject","inherit","componentName","placeholder","inheritedValue","placeholderIsPassword","isUndefined","includes","labelProperty","valueProperty","Criteria","Data","override","disableButtons","notificationForwards","payoneTransactions","transactions","isPayoneTransaction","sort","a","b","createdAt","notificationForwardRepository","repositoryFactory","notificationTargetColumns","width","align","requeue","notificationForward","notificationForwardId","requeueNotificationForward","getNotificationForwards","hasNotificationForwards","criteria","addAssociation","addSorting","addFilter","equals","setLimit","search","api","searchResult","can","permission","acl","isActiveTransaction","stateMachineState","technicalName","hasPayoneTransaction","isPayone","map","match","app","version","parseInt","Module","configuration","description","targetVersion","icon","snippets","deDE","enGB","routeMiddleware","next","currentRoute","routes","component","path","meta","parentPath","settingsItem","to","group","iconComponent","backgroundEnabled","items","sortBy","criteriaLimit","criteriaPage","limit","dataIndex","primary","repository","renderTxactions","getList","context","inheritance","total","onDelete","option","listing","deleteItem","shortcuts","ESCAPE","notificationTargetId","notificationTarget","identifier","notificationTargetIsLoading","notificationTargetRepository","watch","updateSelection","txactions","loadEntityData","State","commit","isInvalid","isBasicAuth","username","password","save","$router","params","exception","onCancel","color","route","requestBody","apiRoute"],"mappings":"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","file":"static/js/payone-payment.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/bundles/payonepayment/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"UZdK\");\n","module.exports = \"{% block payone_notification_target_detail %}\\n \\n\\n {% block payone_notification_target_detail_header %}\\n \\n {% endblock %}\\n\\n {% block payone_notification_target_detail_actions %}\\n \\n {% endblock %}\\n\\n {% block payone_notification_target_detail_content %}\\n \\n\\n {% block payone_notification_target_detail_base_basic_info_card %}\\n \\n \\n \\n {% endblock %}\\n \\n {% endblock %}\\n\\n \\n{% endblock %}\\n\";","const { Application } = Shopware;\nconst ApiService = Shopware.Classes.ApiService;\n\nclass PayonePaymentSettingsService extends ApiService {\n constructor(httpClient, loginService, apiEndpoint = 'payone_payment') {\n super(httpClient, loginService, apiEndpoint);\n }\n\n validateApiCredentials(credentials) {\n const headers = this.getBasicHeaders();\n\n return this.httpClient\n .post(\n `_action/${this.getApiBasePath()}/validate-api-credentials`,\n {\n credentials: credentials,\n },\n {\n headers: headers\n }\n )\n .then((response) => {\n return ApiService.handleResponse(response);\n });\n }\n\n getStateMachineTransitionActions() {\n const headers = this.getBasicHeaders();\n\n return this.httpClient\n .get(\n `_action/${this.getApiBasePath()}/get-state-machine-transition-actions`,\n {\n headers: headers\n }\n )\n .then((response) => {\n return ApiService.handleResponse(response);\n });\n }\n\n hasApplePayCert() {\n const headers = this.getBasicHeaders();\n\n return this.httpClient\n .get(\n `_action/${this.getApiBasePath()}/check-apple-pay-cert`,\n {\n headers: headers\n }\n )\n .catch(() => {\n return false;\n })\n .then((response) => {\n if(!response) {\n return false;\n }\n return true;\n });\n }\n}\n\nApplication.addServiceProvider('PayonePaymentSettingsService', (container) => {\n const initContainer = Application.getContainer('init');\n\n return new PayonePaymentSettingsService(initContainer.httpClient, container.loginService);\n});\n\n","// style-loader: Adds some css to the DOM by adding a