diff --git a/.github/workflows/analysis.yaml b/.github/workflows/analysis.yaml
index a27d6a91..8411f1b8 100644
--- a/.github/workflows/analysis.yaml
+++ b/.github/workflows/analysis.yaml
@@ -19,7 +19,7 @@ jobs:
php:
- 8.2
symfony:
- - '6.2.*'
+ - '6.4.*'
env:
APP_ENV: test
steps:
@@ -38,7 +38,7 @@ jobs:
run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"'
-
name: 'Composer - Set cache'
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: '${{ steps.composer-cache.outputs.dir }}'
key: 'php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-composer-${{ hashFiles(''**/composer.json'') }}'
@@ -58,17 +58,12 @@ jobs:
id: end-of-setup
-
name: 'PHPStan - Run'
- run: 'if [ -f rulesets/phpstan.neon ]; then vendor/bin/phpstan analyse -c rulesets/phpstan.neon src/ ; else echo PHPStan rulesets file does not exist, skipping step ; fi'
- if: 'always() && steps.end-of-setup.outcome == ''success'''
- -
- name: 'PHPSpec - Run'
- run: 'if [ -f phpspec.yml.dist ]; then vendor/bin/phpspec run ; else echo PHPSpec config file does not exist, skipping step ; fi'
- if: 'always() && steps.end-of-setup.outcome == ''success'''
- -
- name: 'Checks security issues - Run'
- run: 'symfony security:check'
+ run: 'if [ -f ruleset/phpstan.neon ]; then vendor/bin/phpstan analyse -c ruleset/phpstan.neon src/ ; else echo PHPStan rulesets file does not exist, skipping step ; fi'
if: 'always() && steps.end-of-setup.outcome == ''success'''
+ # TODO: launch Grumphp
+
sonarcloud:
+ if: github.event.repository.fork != true
runs-on: ubuntu-latest
continue-on-error: true
steps:
diff --git a/.github/workflows/sylius.yaml b/.github/workflows/sylius.yaml
index fbf898ac..15e307f9 100644
--- a/.github/workflows/sylius.yaml
+++ b/.github/workflows/sylius.yaml
@@ -19,12 +19,15 @@ jobs:
matrix:
php:
- 8.2
+ - 8.4
sylius:
- - 1.12.0
+ - 2.1.0
+ - 2.0.0
symfony:
- - 6.2
+ - 6.4
+ - 7.3
node:
- - 14.x
+ - 20.x
env:
APP_ENV: test
package-name: payplug/sylius-payplug-plugin
@@ -43,9 +46,6 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: '${{ matrix.node }}'
- -
- name: 'Wkhtmltopdf - Install'
- run: "sudo apt-get update\nsudo apt-get install xvfb libfontconfig wkhtmltopdf\nprintf '#!/bin/bash\\nxvfb-run -a --server-args=\"-screen 0, 1024x768x24\" /usr/bin/wkhtmltopdf -q $*' | sudo tee /usr/bin/wkhtmltopdf.sh\nsudo chmod a+x /usr/bin/wkhtmltopdf.sh\nsudo ln -s /usr/bin/wkhtmltopdf.sh /usr/local/bin/wkhtmltopdf\n"
-
uses: actions/checkout@v3
-
@@ -54,7 +54,7 @@ jobs:
run: 'echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT'
-
name: 'Composer - Set cache'
- uses: actions/cache@v3
+ uses: actions/cache@v4
id: cache-composer
with:
path: '${{ steps.composer-cache.outputs.dir }}'
@@ -73,48 +73,39 @@ jobs:
run: 'echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT'
-
name: 'Yarn - Set Cache'
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: '${{ steps.yarn-cache.outputs.dir }}'
key: 'node-${{ matrix.node }}-yarn-${{ hashFiles(''**/package.json **/yarn.lock'') }}'
restore-keys: "node-${{ matrix.node }}-yarn-\n"
-
name: 'Install Sylius-Standard and Plugin'
- run: 'make install -e SYLIUS_VERSION=${{ matrix.sylius }} SYMFONY_VERSION=${{ matrix.symfony }} PHP_VERSION=${{ matrix.php }}'
- -
- name: 'Output PHP version for Symfony CLI'
- working-directory: ./tests/Application
- run: 'php -v | head -n 1 | awk ''{ print $2 }'' > .php-version'
+ run: 'make install -e SYLIUS_VERSION=${{ matrix.sylius }} SYMFONY_VERSION=${{ matrix.symfony }}'
-
name: 'Install certificates'
- working-directory: ./tests/Application
run: 'symfony server:ca:install'
-
name: 'Run Chrome headless'
- working-directory: ./tests/Application
run: 'google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server=''direct://'' --proxy-bypass-list=''*'' https://127.0.0.1 > /dev/null 2>&1 &'
-
name: 'Run webserver'
- working-directory: ./tests/Application
- run: 'symfony server:start --port=8080 --dir=public --daemon'
+ run: 'symfony server:start --port=8080 --daemon'
id: end-of-setup-sylius
-
name: 'Doctrine Schema Validate - Run'
- working-directory: ./tests/Application
- run: 'php bin/console doctrine:schema:validate --skip-sync'
+ run: 'vendor/bin/console doctrine:schema:validate --skip-sync'
-
name: 'Run PHPUnit'
run: 'make phpunit'
if: 'always() && steps.end-of-setup-sylius.outcome == ''success'''
- -
- name: 'Configure Behat'
- run: 'make behat-configure'
- if: 'always() && steps.end-of-setup-sylius.outcome == ''success'''
- -
- name: 'Run behat'
- working-directory: ./tests/Application
- run: 'vendor/bin/behat --strict --no-interaction -f progress || vendor/bin/behat --strict -vvv --no-interaction --rerun'
- if: 'always() && steps.end-of-setup-sylius.outcome == ''success'''
+# -
+# name: 'Configure Behat'
+# run: 'make behat-configure'
+# if: 'always() && steps.end-of-setup-sylius.outcome == ''success'''
+# -
+# name: 'Run behat'
+# run: 'vendor/bin/behat --strict --no-interaction -f progress || vendor/bin/behat --strict -vvv --no-interaction --rerun'
+# if: 'always() && steps.end-of-setup-sylius.outcome == ''success'''
-
uses: actions/upload-artifact@v4
if: failure()
diff --git a/.gitignore b/.gitignore
index 88b66083..19975f9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,7 @@
/.idea
*.map
+
+/tests/TestApplication/.env.local
+/tests/TestApplication/.env.*.local
+/var/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..7be32a5b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,33 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [2.0.0] - Unreleased
+
+### Added
+- Support for Sylius v2.0+
+- PHP 8.2+ compatibility
+- Use Payment Request API from Sylius
+- New Unified Authentication System (OAuth2)
+
+> [!IMPORTANT]
+> Merchants will need to contact support to switch to the new authentication method.
+
+### Changed
+- Plugin structure has been changed to follow the new Symfony bundle structure
+- Front assets have been migrated to use Stimulus
+
+### Removed
+- Drop Payum support
+- Drop Sylius 1.x support
+- Drop usage of Secret key - Use OAuth2 instead
+
+Please refer to [github releases](https://github.com/payplug/SyliusPayPlugPlugin/releases) for historical release information.
+
+---
+
+For migration guides and upgrade instructions, see [UPGRADE.md](UPGRADE.md).
+For contributing guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 30982a48..8c9b7307 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,7 +6,7 @@ From the plugin root directory, run the following commands:
$ make install -e SYLIUS_VERSION=XX SYMFONY_VERSION=YY PHP_VERSION=ZZ
```
-Default values : XX=1.12.0 and YY=6.1 and ZZ=8.1
+Default values : XX=1.14.0 and YY=6.4 and ZZ=8.2
To be able to setup the plugin database, remember to configure you database credentials
in `install/Application/.env.local` and `install/Application/.env.test.local`.
@@ -22,7 +22,7 @@ $ make reset
- GrumPHP (see configuration [grumphp.yml](grumphp.yml).)
- GrumPHP is executed by the Git pre-commit hook, but you can launch it manualy with :
+ GrumPHP is executed by the Git pre-commit hook, but you can launch it manually with :
```bash
$ make grumphp
diff --git a/Makefile b/Makefile
index cc5d2e48..b3007cc4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,91 +1,42 @@
.DEFAULT_GOAL := help
SHELL=/bin/bash
COMPOSER_ROOT=composer
-TEST_DIRECTORY=tests/Application
-CONSOLE=cd tests/Application && php bin/console -e test
-COMPOSER=cd tests/Application && composer
-YARN=cd tests/Application && yarn
-
-SYLIUS_VERSION=1.12.0
-SYMFONY_VERSION=6.1
-PHP_VERSION=8.1
+TEST_DIRECTORY=tests/TestApplication
+CONSOLE=vendor/bin/console
+COMPOSER=composer
+SYLIUS_VERSION=2.1.0
+SYMFONY_VERSION=6.4
PLUGIN_NAME=payplug/sylius-payplug-plugin
###
### DEVELOPMENT
### ¯¯¯¯¯¯¯¯¯¯¯
-
-install: sylius ## Install Plugin on Sylius [SYLIUS_VERSION=1.12.0] [SYMFONY_VERSION=6.1] [PHP_VERSION=8.1]
+install: sylius ## Install all dependencies with [SYLIUS_VERSION=2.1.0] [SYMFONY_VERSION=6.4]
.PHONY: install
reset: ## Remove dependencies
-ifneq ("$(wildcard tests/Application/bin/console)","")
${CONSOLE} doctrine:database:drop --force --if-exists || true
-endif
- rm -rf tests/Application
+ rm -rf vendor
.PHONY: reset
-phpunit: phpunit-configure phpunit-run ## Run PHPUnit
+phpunit: ## Run PHPUnit tests
+ ./vendor/bin/phpunit
.PHONY: phpunit
###
### OTHER
### ¯¯¯¯¯¯
-
-sylius: sylius-standard install-plugin install-sylius
+sylius: install-sylius
.PHONY: sylius
-sylius-standard:
-ifeq ($(shell [[ $(SYLIUS_VERSION) == *dev ]] && echo true ),true)
- ${COMPOSER_ROOT} create-project sylius/sylius-standard:${SYLIUS_VERSION} ${TEST_DIRECTORY} --no-install --no-scripts
-else
- ${COMPOSER_ROOT} create-project sylius/sylius-standard ${TEST_DIRECTORY} "~${SYLIUS_VERSION}" --no-install --no-scripts
-endif
- ${COMPOSER} config allow-plugins true
-ifeq ($(shell [[ $(SYLIUS_VERSION) == *dev ]] && echo true ),true)
- ${COMPOSER} require sylius/sylius:"${SYLIUS_VERSION}"
-else
- ${COMPOSER} require sylius/sylius:"~${SYLIUS_VERSION}"
-endif
-
-install-plugin:
- ${COMPOSER} config repositories.plugin '{"type": "path", "url": "../../"}'
- ${COMPOSER} config extra.symfony.allow-contrib true
- ${COMPOSER} config minimum-stability "dev"
- ${COMPOSER} config prefer-stable true
- ${COMPOSER} require "${PLUGIN_NAME}:*" --prefer-source --no-scripts
-
- cp -r install/Application tests
- sed -i "4a \ \ \ \ form_themes: ['form/form_gateway_config_row.html.twig']" ${TEST_DIRECTORY}/config/packages/twig.yaml
- mkdir -p ${TEST_DIRECTORY}/templates/form/
- cp -R src/Resources/views/form/* ${TEST_DIRECTORY}/templates/form/
-
-# As of sylius/refund-plugin 1.2 the folder does not exist anymore
-ifneq ($(PHP_VERSION), 8)
- mkdir -p ${TEST_DIRECTORY}/templates/bundles/SyliusAdminBundle/
- cp -R src/Resources/views/SyliusAdminBundle/* ${TEST_DIRECTORY}/templates/bundles/SyliusAdminBundle/
-endif
-
install-sylius:
- #${CONSOLE} sylius:install -n -s default
- ${CONSOLE} doctrine:database:create -n
- ${CONSOLE} messenger:setup-transports -n
- ${CONSOLE} doctrine:migration:migrate -n
- ${CONSOLE} sylius:fixture:load -n
- ${YARN} install
- ${YARN} build
- ${YARN} gulp
- ${CONSOLE} translation:extract en PayPlugSyliusPayPlugPlugin --dump-messages
- ${CONSOLE} translation:extract fr PayPlugSyliusPayPlugPlugin --dump-messages
-
- ${CONSOLE} cache:clear
+ @echo "Installing Sylius ${SYLIUS_VERSION} using TestApplication"
+ ${COMPOSER} config extra.symfony.require "^${SYMFONY_VERSION}"
+ ${COMPOSER} install
+ ${COMPOSER} require --dev sylius/test-application:"^${SYLIUS_VERSION}@alpha" -n -W # TODO: Remove alpha when stable
+ ${COMPOSER} test-application:install
-phpunit-configure:
- cp phpunit.xml.dist ${TEST_DIRECTORY}/phpunit.xml
- echo -e "\nMOCK_SERVER_HOST=localhost\nMOCK_SERVER_PORT=8987\n" >> ${TEST_DIRECTORY}/.env.test.local
-phpunit-run:
- cd ${TEST_DIRECTORY} && ./vendor/bin/phpunit
behat-configure: ## Configure Behat
(cd ${TEST_DIRECTORY} && cp behat.yml.dist behat.yml)
@@ -101,7 +52,7 @@ grumphp:
vendor/bin/grumphp run
help: SHELL=/bin/bash
-help: ## Dislay this help
+help: ## Display this help
@IFS=$$'\n'; for line in `grep -h -E '^[a-zA-Z_#-]+:?.*?##.*$$' $(MAKEFILE_LIST)`; do if [ "$${line:0:2}" = "##" ]; then \
echo $$line | awk 'BEGIN {FS = "## "}; {printf "\033[33m %s\033[0m\n", $$2}'; else \
echo $$line | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m%s\n", $$1, $$2}'; fi; \
diff --git a/README.md b/README.md
index 7f1e8df1..5d2f4eea 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,7 @@ In local environment, the plugin will not work properly because you will not be
```shell
mkdir -p templates/bundles/SyliusAdminBundle/
- cp -R vendor/payplug/sylius-payplug-plugin/src/Resources/views/SyliusAdminBundle/* templates/bundles/SyliusAdminBundle/
+ cp -R vendor/payplug/sylius-payplug-plugin/templates/SyliusAdminBundle/* templates/bundles/SyliusAdminBundle/
```
4. Add Payplug to refundable payment method for Sylius Refund Plugin in `config/services.yaml`
@@ -70,7 +70,7 @@ In local environment, the plugin will not work properly because you will not be
```yaml
sylius_payplug:
- resource: "@PayPlugSyliusPayPlugPlugin/Resources/config/routing.yaml"
+ resource: "@PayPlugSyliusPayPlugPlugin/config/routing.yaml"
```
8. Add Traits for Customer and PaymentMethod entities
@@ -85,6 +85,7 @@ In local environment, the plugin will not work properly because you will not be
namespace App\Entity\Customer;
use Doctrine\ORM\Mapping as ORM;
+ use PayPlug\SyliusPayPlugPlugin\Entity\CardsOwnerInterface;
use PayPlug\SyliusPayPlugPlugin\Entity\Traits\CustomerTrait;
use Sylius\Component\Core\Model\Customer as BaseCustomer;
@@ -94,7 +95,7 @@ In local environment, the plugin will not work properly because you will not be
*/
#[ORM\Entity]
#[ORM\Table(name: 'sylius_customer')]
- class Customer extends BaseCustomer
+ class Customer extends BaseCustomer implements CardsOwnerInterface
{
use CustomerTrait;
}
@@ -209,9 +210,9 @@ Copy Sylius templates overridden in plugin to your templates directory (e.g temp
mkdir -p templates/bundles/SyliusAdminBundle/
mkdir -p templates/bundles/SyliusShopBundle/
mkdir -p templates/bundles/SyliusUiBundle/
-cp -R vendor/payplug/sylius-payplug-plugin/src/Resources/views/SyliusAdminBundle/* templates/bundles/SyliusAdminBundle/
-cp -R vendor/payplug/sylius-payplug-plugin/src/Resources/views/SyliusShopBundle/* templates/bundles/SyliusShopBundle/
-cp -R vendor/payplug/sylius-payplug-plugin/src/Resources/views/SyliusUiBundle/* templates/bundles/SyliusUiBundle/
+cp -R vendor/payplug/sylius-payplug-plugin/templates/SyliusAdminBundle/* templates/bundles/SyliusAdminBundle/
+cp -R vendor/payplug/sylius-payplug-plugin/templates/SyliusShopBundle/* templates/bundles/SyliusShopBundle/
+cp -R vendor/payplug/sylius-payplug-plugin/templates/SyliusUiBundle/* templates/bundles/SyliusUiBundle/
```
You also need to edit your twig config to add your path to avoid our configuration to be prepended :
diff --git a/RELEASE.md b/RELEASE.md
index 7f73a0af..6cc12383 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -1,4 +1,6 @@
# Release Process
Upon releasing a new version there are checks and updates to be made:
-* Update plugin's version inside `src/PayPlugSyliusPayPlugPlugin.php` and `src/Resources/dev/package.json`
+* Update plugin's version inside `src/PayPlugSyliusPayPlugPlugin.php`
+* Ensure that the `CHANGELOG.md` is up to date with the changes made
+* Ensure that the date of the release version is updated in `CHANGELOG.md`
diff --git a/src/Resources/dev/.eslintignore b/assets/.eslintignore
similarity index 100%
rename from src/Resources/dev/.eslintignore
rename to assets/.eslintignore
diff --git a/src/Resources/dev/.eslintrc b/assets/.eslintrc
similarity index 100%
rename from src/Resources/dev/.eslintrc
rename to assets/.eslintrc
diff --git a/src/Resources/dev/.gitignore b/assets/.gitignore
similarity index 100%
rename from src/Resources/dev/.gitignore
rename to assets/.gitignore
diff --git a/assets/admin/entrypoint.js b/assets/admin/entrypoint.js
new file mode 100644
index 00000000..9ccfccbe
--- /dev/null
+++ b/assets/admin/entrypoint.js
@@ -0,0 +1 @@
+// Mandatory by test application
diff --git a/assets/controllers.json b/assets/controllers.json
new file mode 100644
index 00000000..5582d953
--- /dev/null
+++ b/assets/controllers.json
@@ -0,0 +1,41 @@
+{
+ "controllers": {
+ "@payplug/sylius-payplug-plugin": {
+ "oney-popin": {
+ "enabled": true,
+ "fetch": "lazy",
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/oney_common/index.css": true,
+ "@payplug/sylius-payplug-plugin/shop/dist/oney_popin/index.css": true
+ }
+ },
+ "integrated-payment": {
+ "enabled": true,
+ "fetch": "lazy",
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/payment/integrated.css": true
+ }
+ },
+ "oney-payment": {
+ "enabled": true,
+ "fetch": "lazy"
+ },
+ "payment-logo": {
+ "enabled": true,
+ "fetch": "lazy"
+ },
+ "checkout-select-payment": {
+ "enabled": true,
+ "fetch": "lazy",
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/payment/index.css": true
+ }
+ },
+ "apple-pay": {
+ "enabled": true,
+ "fetch": "lazy"
+ }
+ }
+ },
+ "entrypoints": []
+}
diff --git a/src/Resources/dev/images/integrated/account.svg b/assets/images/integrated/account.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/account.svg
rename to assets/images/integrated/account.svg
diff --git a/src/Resources/dev/images/integrated/calendar.svg b/assets/images/integrated/calendar.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/calendar.svg
rename to assets/images/integrated/calendar.svg
diff --git a/src/Resources/dev/images/integrated/card.svg b/assets/images/integrated/card.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/card.svg
rename to assets/images/integrated/card.svg
diff --git a/src/Resources/dev/images/integrated/cb-dark.svg b/assets/images/integrated/cb-dark.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/cb-dark.svg
rename to assets/images/integrated/cb-dark.svg
diff --git a/src/Resources/dev/images/integrated/cb.svg b/assets/images/integrated/cb.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/cb.svg
rename to assets/images/integrated/cb.svg
diff --git a/src/Resources/dev/images/integrated/lock.svg b/assets/images/integrated/lock.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/lock.svg
rename to assets/images/integrated/lock.svg
diff --git a/src/Resources/dev/images/integrated/logo-payplug.png b/assets/images/integrated/logo-payplug.png
similarity index 100%
rename from src/Resources/dev/images/integrated/logo-payplug.png
rename to assets/images/integrated/logo-payplug.png
diff --git a/src/Resources/dev/images/integrated/mastercard-dark.svg b/assets/images/integrated/mastercard-dark.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/mastercard-dark.svg
rename to assets/images/integrated/mastercard-dark.svg
diff --git a/src/Resources/dev/images/integrated/mastercard.svg b/assets/images/integrated/mastercard.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/mastercard.svg
rename to assets/images/integrated/mastercard.svg
diff --git a/src/Resources/dev/images/integrated/visa-dark.svg b/assets/images/integrated/visa-dark.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/visa-dark.svg
rename to assets/images/integrated/visa-dark.svg
diff --git a/src/Resources/dev/images/integrated/visa.svg b/assets/images/integrated/visa.svg
similarity index 100%
rename from src/Resources/dev/images/integrated/visa.svg
rename to assets/images/integrated/visa.svg
diff --git a/assets/package.json b/assets/package.json
new file mode 100644
index 00000000..52494447
--- /dev/null
+++ b/assets/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "@payplug/sylius-payplug-plugin",
+ "license": "MIT",
+ "version": "2.0.0",
+ "keywords": [
+ "symfony-ux"
+ ],
+ "description": "Sylius Payplug Plugin",
+ "type": "module",
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "symfony": {
+ "controllers": {
+ "oney-popin": {
+ "main": "shop/controllers/oney-popin_controller.js",
+ "enabled": true,
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/oney_common/index.css": true,
+ "@payplug/sylius-payplug-plugin/shop/dist/oney_popin/index.css": true
+ }
+ },
+ "integrated-payment": {
+ "main": "shop/controllers/integrated-payment_controller.js",
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "enabled": true,
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/payment/integrated.css": true
+ }
+ },
+ "oney-payment": {
+ "main": "shop/controllers/oney-payment_controller.js",
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "enabled": true
+ },
+ "payment-logo": {
+ "main": "shop/controllers/payment-logo_controller.js",
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "enabled": true
+ },
+ "checkout-select-payment": {
+ "main": "shop/controllers/checkout-select-payment_controller.js",
+ "autoimport": {
+ "@payplug/sylius-payplug-plugin/shop/dist/payment/index.css": true
+ },
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "enabled": true
+ },
+ "apple-pay": {
+ "main": "shop/controllers/apple-pay_controller.js",
+ "webpackMode": "lazy",
+ "fetch": "lazy",
+ "enabled": true
+ }
+ }
+ },
+ "peerDependencies": {
+ "@hotwired/stimulus": "^3.0.0"
+ },
+ "devDependencies": {
+ "@hotwired/stimulus": "^3.0.0"
+ },
+ "dependencies": {
+ "jquery": "^3.5.1",
+ "webfontloader": "^1.6.28"
+ }
+}
diff --git a/assets/shop/controllers/apple-pay_controller.js b/assets/shop/controllers/apple-pay_controller.js
new file mode 100644
index 00000000..e9d99adc
--- /dev/null
+++ b/assets/shop/controllers/apple-pay_controller.js
@@ -0,0 +1,166 @@
+import { Controller } from '@hotwired/stimulus';
+import $ from 'jquery';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ connect() {
+ this.applePayHandler();
+ }
+ showApplePayButton() {
+ const applePayButton = $(document).find("apple-pay-button");
+ if (applePayButton.length) {
+ applePayButton.addClass('enabled');
+ }
+ }
+ hideApplePayButton() {
+ const applePayButton = $(document).find("apple-pay-button.enabled");
+ if (applePayButton.length) {
+ applePayButton.removeClass('enabled');
+ }
+ }
+ applePayHandler() {
+ const applePayChoice = $(".payment-item .checkbox-applepay input:radio");
+ if (applePayChoice) {
+ if (applePayChoice.is(':checked')) {
+ this.disableNextStepButton();
+ this.showApplePayButton();
+ } else {
+ this.enableNextStepButton();
+ this.hideApplePayButton();
+ }
+ }
+ $(".payment-item .checkbox input:radio").on('change', this.onPaymentMethodChoice);
+ $(document).find("apple-pay-button").on('click', this.onApplePayButtonClick);
+ }
+ onPaymentMethodChoice(event) {
+ const isApplePay = $(event.currentTarget).closest('.checkbox-applepay').length;
+ if (isApplePay) {
+ this.showApplePayButton();
+ this.disableNextStepButton();
+ } else {
+ this.hideApplePayButton();
+ this.enableNextStepButton();
+ }
+ }
+ onApplePayButtonClick(event) {
+ const applePayButton = $(event.currentTarget);
+
+ if (applePaySessionRequestSettings === undefined) {
+ console.error('Invalid Apple Pay settings!');
+ return false;
+ }
+
+ // Create ApplePaySession
+ const session = new ApplePaySession(3, applePaySessionRequestSettings);
+
+ session.onvalidatemerchant = async event => {
+ $.ajax({
+ url: applePayButton.data('validate-merchant-route'),
+ method: 'POST',
+ cache: false,
+ data: {},
+ success: (authorization) => {
+ let result = authorization.merchant_session;
+ console.log(result);
+
+ if (authorization.success === true) {
+ console.log(authorization.merchant_session);
+ session.completeMerchantValidation(result);
+ } else {
+ session.abort();
+ }
+ },
+ error: (XHR, status, error) => {
+ console.log(XHR, status, error);
+ session.abort();
+ window.location.reload();
+ },
+ });
+ };
+
+ session.onpaymentauthorized = event => {
+ $.ajax({
+ url: applePayButton.data('payment-authorized-route'),
+ method: 'POST',
+ cache: false,
+ data: {
+ token: event.payment.token
+ },
+ success: (authorization) => {
+ try {
+ var apple_pay_Session_status = ApplePaySession.STATUS_SUCCESS;
+
+ console.log(authorization);
+ console.log(authorization.data.responseToApple.status);
+ if (authorization.data.responseToApple.status != 1) {
+ apple_pay_Session_status = ApplePaySession.STATUS_FAILURE;
+ }
+
+ const result = {
+ "status": apple_pay_Session_status
+ };
+
+ console.log(apple_pay_Session_status);
+ console.log(result);
+
+ session.completePayment(result);
+
+ console.log(authorization.data.returnUrl);
+ window.location.href = authorization.data.returnUrl;
+ } catch (err) {
+ console.error(err);
+ window.location.reload();
+ }
+ },
+ error: (XHR, status, error) => {
+ console.log(XHR, status, error);
+ session.abort();
+ window.location.reload();
+ },
+ });
+ };
+
+ session.oncancel = event => {
+ console.log('Cancelling Apple Pay session!');
+
+ $.ajax({
+ url: applePayButton.data('session-cancel-route'),
+ cache: false,
+ method: 'POST',
+ data: {},
+ success: (authorization) => {
+ console.log('Cancelled!');
+ console.log(authorization.data.returnUrl);
+ window.location.href = authorization.data.returnUrl;
+ },
+ error: (XHR, status, error) => {
+ console.log(XHR, status, error);
+ window.location.reload();
+ },
+ });
+ };
+
+ session.begin();
+ }
+ disableNextStepButton() {
+ const nextStepButton = $('form[name*="checkout_select_payment"] [data-test-next-step]');
+ nextStepButton.replaceWith(
+ $("", {
+ id: 'next-step',
+ class: 'btn btn-primary btn-icon',
+ html: nextStepButton.html()
+ })
+ );
+ }
+ enableNextStepButton() {
+ const nextStepButton = $('form[name*="checkout_select_payment"] [data-test-next-step]');
+ nextStepButton.replaceWith(
+ $("", {
+ type: 'submit',
+ id: 'next-step',
+ class: 'btn btn-primary btn-icon',
+ html: nextStepButton.html()
+ })
+ );
+ }
+}
diff --git a/assets/shop/controllers/checkout-select-payment_controller.js b/assets/shop/controllers/checkout-select-payment_controller.js
new file mode 100644
index 00000000..e2a21c74
--- /dev/null
+++ b/assets/shop/controllers/checkout-select-payment_controller.js
@@ -0,0 +1,49 @@
+import { Controller } from '@hotwired/stimulus';
+import $ from 'jquery';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ static targets = ['trigger'];
+ form= null;
+
+ connect() {
+ this.toggleGateway();
+
+ this.form = document.querySelector('form[name*="checkout_select_payment"]');
+ this.form.addEventListener('submit', (event) => {
+ this.handleForm();
+ });
+ }
+ toggleGateway() {
+ let checkedPaymentMethodInput;
+
+ $(this.triggerTargets).each((k, v) => {
+ const paymentMethodInputId = $(v).data('payment-input-id');
+ checkedPaymentMethodInput = $(`#${paymentMethodInputId}:checked`);
+ if (checkedPaymentMethodInput.length) {
+ return false;
+ }
+ })
+
+ if (checkedPaymentMethodInput?.length) {
+ $(`.payment-method-choice[data-payment-input-id="${$(checkedPaymentMethodInput).attr('id')}"]`).show();
+ }
+
+ const $inputs = $('input[id*="checkout_select_payment_payments"]');
+ $inputs.on('change', (event) => {
+ const clickedPaymentMethodId = $(event.currentTarget).attr('id');
+ $('.payment-method-choice').slideUp(); // Hide others
+ $(`.payment-method-choice[data-payment-input-id="${clickedPaymentMethodId}"]`).slideDown(); // Show current
+ });
+ }
+ handleForm() {
+ if ($('.checkbox-oney :radio:checked').length) {
+ $('.checkbox-payplug').closest('.payment-item').find('.payment-choice__input:checked').prop('checked', false);
+ } else if ($('.checkbox-payplug :radio:checked').length) {
+ $('.checkbox-oney').closest('.payment-item').find('.payment-choice__input:checked').prop('checked', false);
+ }
+
+ $('input#payplug_choice_card_other').attr('disabled', true);
+ this.form.submit();
+ }
+}
diff --git a/src/Resources/dev/shop/payment/integrated.js b/assets/shop/controllers/integrated-payment_controller.js
similarity index 52%
rename from src/Resources/dev/shop/payment/integrated.js
rename to assets/shop/controllers/integrated-payment_controller.js
index 861f56c4..4af78c21 100644
--- a/src/Resources/dev/shop/payment/integrated.js
+++ b/assets/shop/controllers/integrated-payment_controller.js
@@ -1,157 +1,198 @@
-const IntegratedPayment = {
- options: {
- api: null,
- cartId: null,
- form: {},
- fieldsValid: {
- cardHolder: false,
- pan: false,
- cvv: false,
- exp: false,
- },
- fieldsEmpty: {
- cardHolder: true,
- pan: true,
- cvv: true,
- exp: true,
- },
- inputStyle: {
- default: {
- color: '#2B343D',
- fontFamily: 'Poppins, Arial, sans-serif',
- fontSize: '14px',
- textAlign: 'left',
- '::placeholder': {
- color: '#969a9f',
- },
- ':focus': {
+import { Controller } from '@hotwired/stimulus';
+import WebFont from 'webfontloader';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ static values = {
+ code: String,
+ factoryName: String,
+ }
+ initialize() {
+ WebFont.load({
+ google: {
+ families: ["Poppins:400,600"],
+ },
+ });
+ }
+ connect() {
+ this.options = {
+ api: null,
+ cartId: null,
+ form: {},
+ fieldsValid: {
+ cardHolder: false,
+ pan: false,
+ cvv: false,
+ exp: false,
+ },
+ fieldsEmpty: {
+ cardHolder: true,
+ pan: true,
+ cvv: true,
+ exp: true,
+ },
+ inputStyle: {
+ default: {
color: '#2B343D',
+ fontFamily: 'Poppins, Arial, sans-serif',
+ fontSize: '14px',
+ textAlign: 'left',
+ '::placeholder': {
+ color: '#969a9f',
+ },
+ ':focus': {
+ color: '#2B343D',
+ }
+ },
+ invalid: {
+ color: '#E91932'
}
},
- invalid: {
- color: '#E91932'
- }
- },
- save_card: false,
- schemes: null,
- scheme: null,
- },
- init() {
+ save_card: false,
+ schemes: null,
+ scheme: null,
+ };
+
+ // Verify if we have required data
+ // TODO: Pass as param
if (payplug_integrated_payment_params === undefined) {
return;
}
+
if (payplug_integrated_payment_params.has_saved_cards) {
document.querySelectorAll('.payment-choice__input, .payment-item input[type=radio]:not([name=schemeOptions])').forEach((element) => {
element.addEventListener('change', (e) => {
if (
- 'payplug_choice_card_other' === e.currentTarget.id && e.currentTarget.checked ||
- e.target.value === payplug_integrated_payment_params.payment_method_code && document.querySelector('#payplug_choice_card_other').checked
+ 'payplug_choice_card_other' === e.currentTarget.id &&
+ e.currentTarget.checked ||
+ e.target.value === payplug_integrated_payment_params.payment_method_code &&
+ document.querySelector('#payplug_choice_card_other').checked
) {
- IntegratedPayment.openFields();
+ this.openFields();
return;
}
- IntegratedPayment.closeFields();
+ this.closeFields();
})
})
return;
}
- if (document.querySelector(`[id*=sylius_checkout_select_payment_payments][value=${payplug_integrated_payment_params.payment_method_code}]:checked`)) {
- IntegratedPayment.openFields();
+
+ const isChecked = this.getPaymentMethodSelectors({ methodCode: payplug_integrated_payment_params.payment_method_code, checked: true });
+ if (isChecked.length) {
+ this.openFields();
}
- document.querySelectorAll('[id*=sylius_checkout_select_payment_payments]').forEach((element) => {
+
+ const selectPaymentMethodsField= this.getPaymentMethodSelectors();
+ selectPaymentMethodsField.forEach((element) => {
+ // On payment method select, open or close card fields
element.addEventListener('change', (e) => {
if (payplug_integrated_payment_params.payment_method_code === e.currentTarget.value && e.currentTarget.checked) {
- IntegratedPayment.openFields();
+ this.openFields();
return;
}
- IntegratedPayment.closeFields();
+ this.closeFields();
})
});
- },
+ }
+ getPaymentMethodSelectors({ methodCode, checked } = {}) {
+ const baseSelector = '[id*=checkout_select_payment_payments]';
+
+ if (methodCode) {
+ if (checked) {
+ return document.querySelectorAll(`${baseSelector}[value=${methodCode}]:checked`);
+ }
+ return document.querySelectorAll(`${baseSelector}[value=${methodCode}]`);
+ }
+ return document.querySelectorAll(baseSelector);
+ }
openFields() {
document.querySelector('.payplugIntegratedPayment').classList.add('payplugIntegratedPayment--loaded');
document.querySelector('button[type=submit]').classList.add('disabled');
- if (null === IntegratedPayment.options.api) {
- IntegratedPayment.load();
+ if (null === this.options.api) {
+ this.load();
}
- },
+ }
closeFields() {
document.querySelector('.payplugIntegratedPayment').classList.remove('payplugIntegratedPayment--loaded');
document.querySelector('button[type=submit]').classList.remove('disabled');
- },
+ }
load() {
- IntegratedPayment.options.api = integratedPaymentApi = new Payplug.IntegratedPayment(payplug_integrated_payment_params.is_test_mode);
- integratedPaymentApi.setDisplayMode3ds(Payplug.DisplayMode3ds.LIGHTBOX);
- IntegratedPayment.options.form.cardHolder = integratedPaymentApi.cardHolder(
+ this.options.api = new Payplug.IntegratedPayment(payplug_integrated_payment_params.is_test_mode);
+
+ this.options.api.setDisplayMode3ds(Payplug.DisplayMode3ds.LIGHTBOX);
+
+ this.options.form.cardHolder = this.options.api.cardHolder(
document.querySelector('.cardHolder-input-container'),
{
- default: IntegratedPayment.options.inputStyle.default,
+ default: this.options.inputStyle.default,
placeholder: payplug_integrated_payment_params.cardholder
}
);
- IntegratedPayment.options.form.pan = integratedPaymentApi.cardNumber(
+ this.options.form.pan = this.options.api.cardNumber(
document.querySelector('.pan-input-container'),
{
- default: IntegratedPayment.options.inputStyle.default,
+ default: this.options.inputStyle.default,
placeholder: payplug_integrated_payment_params.pan
}
);
- IntegratedPayment.options.form.cvv = integratedPaymentApi.cvv(
+ this.options.form.cvv = this.options.api.cvv(
document.querySelector('.cvv-input-container'),
{
- default: IntegratedPayment.options.inputStyle.default,
+ default: this.options.inputStyle.default,
placeholder: payplug_integrated_payment_params.cvv
}
);
- IntegratedPayment.options.form.exp = integratedPaymentApi.expiration(
+ this.options.form.exp = this.options.api.expiration(
document.querySelector('.exp-input-container'),
{
- default: IntegratedPayment.options.inputStyle.default,
+ default: this.options.inputStyle.default,
placeholder: payplug_integrated_payment_params.exp
}
);
- IntegratedPayment.options.schemes = integratedPaymentApi.getSupportedSchemes();
- IntegratedPayment.bindEvents();
- IntegratedPayment.fieldValidation();
- },
+ this.options.schemes = this.options.api.getSupportedSchemes();
+ this.bindEvents();
+ this.fieldValidation();
+ }
bindEvents() {
document.querySelector('#paid').addEventListener('click', (event) => {
event.preventDefault();
- integratedPaymentApi.validateForm();
+
+ this.options.api.validateForm();
});
- integratedPaymentApi.onValidateForm(async ({isFormValid}) => {
+ this.options.api.onValidateForm(async ({ isFormValid }) => {
if (isFormValid) {
this.toggleLoader();
const saveCardElement = document.querySelector('#savecard');
if (null !== saveCardElement) {
- IntegratedPayment.options.save_card = saveCardElement.checked;
+ this.options.save_card = saveCardElement.checked;
}
- const chosenScheme = document.querySelector('[name=schemeOptions]:checked');
- IntegratedPayment.options.scheme = Payplug.Scheme.AUTO;
+ const chosenScheme = document.querySelector('input.schemeOptions:checked');
+ this.options.scheme = Payplug.Scheme.AUTO;
if (null !== chosenScheme) {
- IntegratedPayment.options.scheme = chosenScheme.value;
+ this.options.scheme = chosenScheme.value;
}
if (payplug_integrated_payment_params.payment_id !== undefined) {
- integratedPaymentApi.pay(payplug_integrated_payment_params.payment_id, IntegratedPayment.options.scheme, {save_card: IntegratedPayment.options.save_card});
+ this.options.api.pay(payplug_integrated_payment_params.payment_id, this.options.scheme, {save_card: this.options.save_card});
return;
}
const response = await fetch(payplug_integrated_payment_params.routes.init_payment, {method: 'POST'});
const data = await response.json();
- integratedPaymentApi.pay(data.payment_id, IntegratedPayment.options.scheme, {save_card: IntegratedPayment.options.save_card});
+ this.options.api.pay(data.payment_id, this.options.scheme, {save_card: this.options.save_card});
}
});
- integratedPaymentApi.onCompleted((event) => {
+ this.options.api.onCompleted((event) => {
if (event.error) {
console.error(event.error);
return;
}
document.querySelector('input[name=payplug_integrated_payment_token]').value = event.token;
- document.querySelector('form[name=sylius_checkout_select_payment]').submit();
+ document.querySelector('form[name*="checkout_select_payment"]').submit();
});
- },
+ }
fieldValidation () {
- $.each(IntegratedPayment.options.form, function (key, field) {
- field.onChange(function(err) {
+ Object.keys(this.options.form).forEach((key) => {
+ const field = this.options.form[key];
+ field.onChange((err) => {
if (err.error) {
document.querySelector(`.payplugIntegratedPayment__error--${key}`).classList.remove('payplugIntegratedPayment__error--hide');
document.querySelector(`.${key}-input-container`).classList.add('payplugIntegratedPayment__container--invalid');
@@ -167,15 +208,13 @@ const IntegratedPayment = {
document.querySelector(`.${key}-input-container`).classList.remove('payplugIntegratedPayment__container--invalid');
document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".invalidField").classList.add('payplugIntegratedPayment__error--hide');
document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".emptyField").classList.add('payplugIntegratedPayment__error--hide');
- IntegratedPayment.options.fieldsValid[key] = true;
- IntegratedPayment.options.fieldsEmpty[key] = false;
+ this.options.fieldsValid[key] = true;
+ this.options.fieldsEmpty[key] = false;
}
});
- });
- },
+ })
+ }
toggleLoader() {
- document.querySelector('.payplugIntegratedPayment').querySelector('.dimmer').classList.toggle('active');
+ document.querySelector('.payplugIntegratedPayment').querySelector('.sylius-shop-loader').classList.toggle('d-none');
}
-};
-
-document.addEventListener("DOMContentLoaded", IntegratedPayment.init, false);
+}
diff --git a/assets/shop/controllers/oney-payment_controller.js b/assets/shop/controllers/oney-payment_controller.js
new file mode 100644
index 00000000..bdf7d63e
--- /dev/null
+++ b/assets/shop/controllers/oney-payment_controller.js
@@ -0,0 +1,95 @@
+import { Controller } from '@hotwired/stimulus';
+import $ from 'jquery';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ static values = {
+ modal: String,
+ area: String,
+ route: String,
+ }
+ connect() {
+ this.tabs();
+ window.addEventListener('resize', () => {
+ setTimeout(this.tabs, 100);
+ });
+ this.tabsHandler();
+ }
+ tabs() {
+ if (window.innerWidth <= 991) {
+ $('.oney-payment-choice__item').hide();
+ setTimeout(() => {
+ $.each($('.oney-payment-choice__input'), (k, el) => {
+ if ($(el).is(':checked')) {
+ $(el).parent().show();
+ $(`a.tablink[data-id=${$(el).val()}]`).addClass('active');
+ }
+ });
+ }, 1);
+ } else {
+ $('.oney-payment-choice__item').show();
+ $('a.tablink').removeClass('active');
+ }
+ }
+ tabsHandler() {
+ const $tabLinks = $('a.tablink');
+ $.each($tabLinks, (k, el) => {
+ $(el).click(function (evt) {
+ $('a.tablink').removeClass('active');
+ $(this).addClass('active');
+ $('.oney-payment-choice__item').hide();
+ $(`#${$(this).data('id')}`).show();
+ $(`input[value=${$(this).data('id')}`).prop('checked', true);
+ });
+ });
+ }
+ routeValueChanged() {
+ if (!this.hasRouteValue) {
+ return;
+ }
+ this.modalAppear();
+ }
+ modalAppear() {
+ let path = this.routeValue;
+ $.get(path).then((data) => {
+ const modalTpl = document.querySelector('.modal');
+ this.modal = new window.bootstrap.Modal(modalTpl);
+ $(modalTpl).find('.modal-body').html(data);
+ this.modal.show();
+ this.bindModalEvents();
+ });
+ }
+ modalSubmit(e) {
+ if (!this.hasRouteValue) {
+ return;
+ }
+ e.preventDefault();
+ $('.sylius-shop-loader').toggleClass("d-none");
+ $.ajax({
+ method: 'post',
+ url: this.routeValue,
+ data: $(e.currentTarget).serialize(),
+ success: (res) => {
+ if (Array.isArray(res)) {
+ $(`${this.modalValue}__content`).fadeOut(() => {
+ $(`${this.modalValue}__success`).show();
+ });
+ setTimeout(() => {
+ this.modal.hide();
+ window.location.reload();
+ }, 2500);
+ }
+ },
+ error: (res) => {
+ $(this.modalValue).html(res.responseText);
+ this.bindModalEvents();
+ },
+ complete: () => {
+ $('.sylius-shop-loader').toggleClass("d-none");
+ }
+ });
+ }
+ bindModalEvents() {
+ $('form[name=form]').on('submit', (e) => this.modalSubmit(e));
+ }
+}
diff --git a/assets/shop/controllers/oney-popin_controller.js b/assets/shop/controllers/oney-popin_controller.js
new file mode 100644
index 00000000..e8cc4554
--- /dev/null
+++ b/assets/shop/controllers/oney-popin_controller.js
@@ -0,0 +1,167 @@
+import { Controller } from '@hotwired/stimulus';
+import $ from 'jquery';
+import WebFont from 'webfontloader';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ static targets = ['popin', 'variantCodes'];
+ static values = {
+ eligibleUrl: String,
+ popinUrl: String,
+ productMeta: Object,
+ imagesMap: Object,
+ translations: Object,
+ }
+ inputs = {
+ option: "cartItem_variant",
+ quantity: "cartItem_quantity",
+ }
+ storage = []
+ initialize() {
+ WebFont.load({
+ google: {
+ families: ["Poppins:400,600"],
+ },
+ });
+ }
+ connect() {
+ if (this.hasProductMetaValue) {
+ this.watch();
+ }
+ this.fade();
+ this.closeHandler();
+ }
+ watch() {
+ for (const prop in this.inputs) {
+ const $selectors = $(`[id*=${this.inputs[prop]}`);
+ if ($selectors.length > 0) {
+ this.handleProductOptionsChange($selectors, prop);
+ }
+ this.productMetaValue = {
+ ...this.productMetaValue,
+ [prop]: $selectors.val(),
+ };
+ $selectors.on(
+ "input",
+ this.debounce((e) => {
+ e.preventDefault();
+ if ($selectors.length > 0) {
+ this.handleProductOptionsChange($selectors, prop);
+ }
+ this.productMetaValue = {
+ ...this.productMetaValue,
+ [prop]: $(e.currentTarget).val(),
+ };
+ this.check();
+ }, 500)
+ );
+ }
+ }
+ handleProductOptionsChange($selectors, prop) {
+ if (prop === "option") {
+ let selector = "";
+ $selectors.each((k, v) => {
+ const select = $(v);
+ const option = select.find("option:selected").val();
+ selector += `[data-${select.attr("data-option")}="${option}"]`;
+ });
+ return (this.productMetaValue = {
+ ...this.productMetaValue,
+ product_variant_code: $(this.variantCodesTarget).find(selector).attr("data-value")
+ });
+ }
+ }
+ check() {
+ this.storage = [];
+ this.toggleLoader();
+ $.ajax({
+ url: this.eligibleUrlValue,
+ data: this.productMetaValue,
+ success: (res) => {
+ $(this.element).find(".oney-logo").attr("src", this.imagesMapValue[res.isEligible ? 'enabled' : 'disabled']);
+ res.isEligible
+ ? $(this.popinTarget).removeClass("disabled").addClass("enabled")
+ : $(this.popinTarget).removeClass("enabled").addClass("disabled");
+ },
+ complete: () => {
+ this.toggleLoader();
+ }
+ });
+ }
+ /**
+ * https://davidwalsh.name/javascript-debounce-function
+ */
+ debounce(func, wait) {
+ let timeout;
+ return function executedFunction(...args) {
+ const later = () => {
+ clearTimeout(timeout);
+ func(...args);
+ };
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ };
+ }
+ fade() {
+ $(this.element).on("click", (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (this.hasEligibleUrlValue) {
+ if (!$(this.popinTarget).is(":empty") && $(this.popinTarget).text().trim() === this.storage) {
+ $(this.popinTarget).fadeIn();
+ return;
+ }
+ }
+ // content isn't loaded yet or cart route
+ this.toggleLoader();
+ this.load();
+ });
+ }
+ load() {
+ $.ajax({
+ url: this.popinUrlValue,
+ data: this.productMetaValue,
+ success: (res) => {
+ if (res.includes(this.translationsValue.reason)) {
+ $(this.popinTarget).removeClass("enabled").addClass("disabled");
+ }
+ this.storage = $(res).text().trim();
+ $(this.popinTarget).html(res);
+ },
+ error: ()=> {
+ $(this.popinTarget).removeClass("enabled").addClass("disabled").html(`
+
+
+
${this.translationsValue.reason}
+
+ `);
+ },
+ complete: ()=> {
+ this.toggleLoader();
+ $(this.popinTarget).fadeIn();
+ this.closeHandler();
+ },
+ });
+ }
+ toggleLoader() {
+ $(this.element).find('.sylius-shop-loader').toggleClass("d-none");
+ }
+ closeHandler() {
+ $("html")
+ .not(this.popinTarget)
+ .on("click", (e) => {
+ e.stopPropagation();
+ $(this.popinTarget).fadeOut();
+ });
+ $(this.popinTarget)
+ .find("a.close")
+ .on("click", (e) => {
+ e.stopPropagation();
+ $(this.popinTarget).fadeOut();
+ });
+ }
+}
diff --git a/assets/shop/controllers/payment-logo_controller.js b/assets/shop/controllers/payment-logo_controller.js
new file mode 100644
index 00000000..486cb375
--- /dev/null
+++ b/assets/shop/controllers/payment-logo_controller.js
@@ -0,0 +1,20 @@
+import { Controller } from '@hotwired/stimulus';
+import $ from 'jquery';
+
+/* stimulusFetch: 'lazy' */
+export default class extends Controller {
+ static values = {
+ inputId: String,
+ logoUrl: String,
+ className: String,
+ };
+ connect() {
+ if (!this.inputIdValue || !this.logoUrlValue) {
+ return;
+ }
+
+ const label = document.querySelector(`[for="${this.inputIdValue}"]`);
+ label.style.setProperty('--logo', `url(${this.logoUrlValue})`);
+ label.classList.add('payment-label-with-image', this.classNameValue);
+ }
+}
diff --git a/src/Resources/public/assets/shop/oney_common/index.css b/assets/shop/dist/oney_common/index.css
similarity index 100%
rename from src/Resources/public/assets/shop/oney_common/index.css
rename to assets/shop/dist/oney_common/index.css
diff --git a/src/Resources/public/assets/shop/oney_popin/index.css b/assets/shop/dist/oney_popin/index.css
similarity index 100%
rename from src/Resources/public/assets/shop/oney_popin/index.css
rename to assets/shop/dist/oney_popin/index.css
diff --git a/src/Resources/public/assets/shop/account.039342ad.svg b/assets/shop/dist/payment/account.039342ad.svg
similarity index 100%
rename from src/Resources/public/assets/shop/account.039342ad.svg
rename to assets/shop/dist/payment/account.039342ad.svg
diff --git a/src/Resources/public/assets/shop/calendar.3c23bb16.svg b/assets/shop/dist/payment/calendar.3c23bb16.svg
similarity index 100%
rename from src/Resources/public/assets/shop/calendar.3c23bb16.svg
rename to assets/shop/dist/payment/calendar.3c23bb16.svg
diff --git a/src/Resources/public/assets/shop/card.0d2bd9bc.svg b/assets/shop/dist/payment/card.0d2bd9bc.svg
similarity index 100%
rename from src/Resources/public/assets/shop/card.0d2bd9bc.svg
rename to assets/shop/dist/payment/card.0d2bd9bc.svg
diff --git a/src/Resources/public/assets/shop/cb-dark.888aec45.svg b/assets/shop/dist/payment/cb-dark.888aec45.svg
similarity index 100%
rename from src/Resources/public/assets/shop/cb-dark.888aec45.svg
rename to assets/shop/dist/payment/cb-dark.888aec45.svg
diff --git a/src/Resources/public/assets/shop/cb.ccd964e9.svg b/assets/shop/dist/payment/cb.ccd964e9.svg
similarity index 100%
rename from src/Resources/public/assets/shop/cb.ccd964e9.svg
rename to assets/shop/dist/payment/cb.ccd964e9.svg
diff --git a/assets/shop/dist/payment/index.css b/assets/shop/dist/payment/index.css
new file mode 100644
index 00000000..bb6bfa52
--- /dev/null
+++ b/assets/shop/dist/payment/index.css
@@ -0,0 +1,252 @@
+.oney-payment-choice__item label, .payplug-payment-choice__item label {
+ margin-top: 0 !important;
+ padding: 1em !important;
+ display: flex !important
+}
+
+.oney-payment-choice, .payplug-payment-choice {
+ display: none
+}
+
+.oney-payment-choice__container, .payplug-payment-choice__container {
+ margin: 1rem 0;
+ display: flex
+}
+
+.oney-payment-choice__header p, .payplug-payment-choice__header p {
+ color: #000;
+ margin: .5em 0 !important
+}
+
+.oney-payment-choice__item, .payplug-payment-choice__item {
+ flex: auto
+}
+
+.oney-payment-choice__item--oney_x3_with_fees, .oney-payment-choice__item--oney_x3_without_fees, .payplug-payment-choice__item--oney_x3_with_fees, .payplug-payment-choice__item--oney_x3_without_fees {
+ margin-right: 1em
+}
+
+.oney-payment-choice__item input, .payplug-payment-choice__item input {
+ display: none
+}
+
+.oney-payment-choice__item input:checked + label, .payplug-payment-choice__item input:checked + label {
+ background-color: #81bc0021;
+ border-color: #81bc00
+}
+
+.oney-payment-choice__item input:checked + label.payplug-payment-choice__label, .payplug-payment-choice__item input:checked + label.payplug-payment-choice__label {
+ background-color: #8fd2b821;
+ border-color: #8fd2b8
+}
+
+.oney-payment-choice__item label, .payplug-payment-choice__item label {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ border: 1px solid #ccc;
+ border-radius: .285714rem;
+ flex-direction: column;
+ transition: border-color, background-color .3s ease-in-out;
+ position: relative;
+ box-shadow: 0 1px 2px #22242626
+}
+
+.oney-payment-choice__item label img, .payplug-payment-choice__item label img {
+ vertical-align: text-bottom
+}
+
+.oney-payment-choice__content, .payplug-payment-choice__content {
+ display: contents
+}
+
+.oney-payment-choice__content p, .payplug-payment-choice__content p {
+ color: #000;
+ border-bottom: 1px solid #ccc;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ display: flex;
+ margin: 0 !important;
+ padding: .75rem 0 !important
+}
+
+.oney-payment-choice__content p:nth-last-of-type(2), .payplug-payment-choice__content p:nth-last-of-type(2) {
+ margin-bottom: 1rem !important
+}
+
+.oney-payment-choice__content p:last-of-type, .payplug-payment-choice__content p:last-of-type {
+ border: none;
+ margin-top: auto !important;
+ margin-bottom: 0 !important
+}
+
+.oney-payment-choice__content p.oney-without-fees-financing, .payplug-payment-choice__content p.oney-without-fees-financing {
+ display: inline-block
+}
+
+.oney-payment-choice__content small, .payplug-payment-choice__content small {
+ margin-top: .5rem;
+ font-size: 80%
+}
+
+.oney-payment-choice__tab {
+ display: none
+}
+
+.oney-payment-choice__header {
+ text-align: center;
+ margin: 0 auto
+}
+
+[data-gateway=oney] {
+ margin-top: 10px !important;
+ padding: 0 !important
+}
+
+.payment-item .oney-logo[src*=without-fees] {
+ max-width: 200px
+}
+
+.payment-item apple-pay-button {
+ --apple-pay-button-width: 222px;
+ --apple-pay-button-height: 40px;
+ --apple-pay-button-border-radius: 4px;
+ --apple-pay-button-padding: 4px 4px;
+ --apple-pay-button-box-sizing: border-box;
+ min-width: 140px;
+ max-width: 100%;
+ transition: background-color .3s ease-in-out;
+ display: none
+}
+
+.payment-item apple-pay-button.enabled {
+ display: block
+}
+
+.payment-item label {
+ cursor: pointer
+}
+
+.payment-item .bancontact-method label, .payment-item .apple-pay-method label, .payment-item .american-express-method label {
+ position: relative
+}
+
+.payment-item .bancontact-method label img, .payment-item .apple-pay-method label img, .payment-item .american-express-method label img {
+ margin-left: .5em;
+ position: absolute;
+ top: -12px;
+ left: 100%
+}
+
+.payplug-payment-choice__container {
+ flex-direction: column
+}
+
+.payplug-payment-choice__item {
+ margin-bottom: 1em
+}
+
+.payplug-payment-choice__header {
+ justify-content: space-between;
+ align-items: center;
+ display: flex
+}
+
+.payplug-payment-choice__header .card-expiry span {
+ font-weight: 700
+}
+
+.oney-complete-info-popin {
+ max-width: 480px;
+ margin: auto;
+}
+
+.oney-complete-info-popin__content ul {
+ padding: 0;
+ list-style: none
+}
+
+.oney-complete-info-popin__success {
+ display: none
+}
+
+.payment-label-with-image::after {
+ content: "";
+ background-image: var(--logo);
+ display: inline-block;
+ width: 60px;
+ height: 25px;
+ background-repeat: no-repeat;
+ background-position: 0 -11px;
+ background-size: 60px 45px;
+ float: right
+}
+
+.bancontact-label::after {
+ margin-left: 5px
+}
+
+@media screen and (max-width: 991px) {
+ .oney-payment-choice__container, .payplug-payment-choice__container {
+ display: block
+ }
+
+ .oney-payment-choice__content small, .payplug-payment-choice__content small {
+ width: 100%
+ }
+
+ .oney-payment-choice__tab {
+ justify-content: space-between;
+ display: flex
+ }
+
+ .oney-payment-choice__tab .tablink {
+ text-align: center;
+ border: 1px solid #ccc;
+ border-bottom: 0;
+ flex: 1;
+ padding: 1rem 0
+ }
+
+ .oney-payment-choice__tab .tablink.active {
+ border-bottom: 5px solid #81bc00
+ }
+
+ .oney-payment-choice__tab .tablink p {
+ color: #000
+ }
+
+ .oney-payment-choice__tab .tablink:first-of-type {
+ border-right: 0
+ }
+
+ .oney-payment-choice__tab .tablink > .oney-payment__image {
+ max-width: 120px
+ }
+
+ .oney-payment-choice__header, .oney-payment-choice__item {
+ display: none
+ }
+
+ .oney-payment-choice__item input:checked + label {
+ background-color: #fff;
+ border-color: #ccc
+ }
+
+ .oney-payment-choice__item label {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0
+ }
+
+ .oney-payment-choice__item--oney_x3_with_fees, .oney-payment-choice__item--oney_x3_without_fees {
+ margin-bottom: 1rem;
+ margin-right: 0;
+ display: block
+ }
+}
+
+@media screen and (max-width: 480px) {
+ .payplug-payment-choice__header, .payplug-payment-choice__header .card-type, .payplug-payment-choice__header .card-expiry {
+ display: block
+ }
+}
diff --git a/assets/shop/dist/payment/integrated.css b/assets/shop/dist/payment/integrated.css
new file mode 100644
index 00000000..9a2805f7
--- /dev/null
+++ b/assets/shop/dist/payment/integrated.css
@@ -0,0 +1 @@
+.payplugIntegratedPayment{justify-self:center;display:none}.payplugIntegratedPayment *{font-family:Poppins,Arial,sans-serif!important}.payplugIntegratedPayment--loaded{width:100%;max-width:400px;flex-wrap:wrap;justify-content:space-between;margin-top:20px;margin-bottom:0;display:flex;position:relative}.payplugIntegratedPayment__select{height:36px;width:100%;border:1px solid #ccc;border-radius:5px;margin:0 0 10px;padding:0 8px}.payplugIntegratedPayment__container{width:100%;margin:0 0 10px;padding:0;display:flex;position:relative}.payplugIntegratedPayment__container--cardHolder,.payplugIntegratedPayment__container--pan,.payplugIntegratedPayment__container--exp,.payplugIntegratedPayment__container--cvv{height:40px;cursor:text;border:1px solid #d5d6d8;border-radius:2px;padding:0 16px 0 50px;line-height:40px}.payplugIntegratedPayment__container--cardHolder:before,.payplugIntegratedPayment__container--pan:before,.payplugIntegratedPayment__container--exp:before,.payplugIntegratedPayment__container--cvv:before{content:"";width:24px;height:24px;background:#95999e 50%/100% no-repeat;position:absolute;top:20%;left:16px}.payplugIntegratedPayment__container--cardHolder:focus,.payplugIntegratedPayment__container--pan:focus,.payplugIntegratedPayment__container--exp:focus,.payplugIntegratedPayment__container--cvv:focus{border-color:#2b343d}.payplugIntegratedPayment__container--cardHolder--invalid,.payplugIntegratedPayment__container--pan--invalid,.payplugIntegratedPayment__container--exp--invalid,.payplugIntegratedPayment__container--cvv--invalid{border-color:#e91932}.payplugIntegratedPayment__container--cardHolder:before{-webkit-mask-image:url(account.039342ad.svg);mask-image:url(account.039342ad.svg)}.payplugIntegratedPayment__container--pan:before{-webkit-mask-image:url(card.0d2bd9bc.svg);mask-image:url(card.0d2bd9bc.svg)}.payplugIntegratedPayment__container--exp:before{-webkit-mask-image:url(calendar.3c23bb16.svg);mask-image:url(calendar.3c23bb16.svg)}.payplugIntegratedPayment__container--cvv:before{-webkit-mask-image:url(lock.fe8a73cd.svg);mask-image:url(lock.fe8a73cd.svg)}.payplugIntegratedPayment__container--exp,.payplugIntegratedPayment__container--cvv{max-width:calc(50% - 2px);display:inline-block}.payplugIntegratedPayment__container--scheme{text-transform:uppercase;height:22px;justify-content:space-between;align-items:center;margin:10px 0;font-size:14px;font-weight:700}.payplugIntegratedPayment__container--saveCard{height:auto;align-items:center;padding:10px 0 0;display:flex}.payplugIntegratedPayment__container--saveCard input{display:none}.payplugIntegratedPayment__container--saveCard input:checked+label span:before{opacity:1}.payplugIntegratedPayment__container--saveCard label{cursor:pointer;color:#918f8f;margin:0!important;font-size:12px!important}.payplugIntegratedPayment__container--saveCard label span{cursor:pointer;height:16px;-o-transition:border .4s;width:16px;border:1px solid #d5d6d8;border-radius:2px;margin:0 10px -3px 0;transition:border .4s;display:inline-block;position:relative}.payplugIntegratedPayment__container--saveCard label span:before{content:"";height:5px;opacity:0;width:10px;border-top:none;border-bottom:2.5px solid #2b343d;border-left:2.5px solid #2b343d;border-right:none;border-radius:1px;transition:opacity .4s;display:block;position:absolute;top:50%;left:50%;transform:translate(-50%,-55%)rotate(-48deg)}.payplugIntegratedPayment__container--saveCard label:hover{color:#2b343d;transition:all .1s}.payplugIntegratedPayment__container--saveCard label:hover span{border-color:#2b343d;transition:all .1s}.payplugIntegratedPayment__container--transaction{align-items:center;margin-top:10px}.payplugIntegratedPayment__container--transaction .transaction-label{vertical-align:super;margin-left:5px;font-size:12px}.payplugIntegratedPayment__container img.lock-icon{width:18px;float:left!important}.payplugIntegratedPayment__container img.payplug-logo{width:80px;height:auto;vertical-align:text-top;margin-left:6px;display:inline-block;float:inherit!important}.payplugIntegratedPayment__container--privacy-policy{text-align:center;display:inline-block}.payplugIntegratedPayment__container--privacy-policy a{color:#918f8f;font-size:14px}.payplugIntegratedPayment__schemes{width:115px;flex-wrap:wrap;justify-content:space-between;align-items:center;display:flex}.payplugIntegratedPayment__schemes label{display:table-cell}.payplugIntegratedPayment__scheme{margin:0}.payplugIntegratedPayment__scheme span{cursor:pointer;width:33px;height:22px;background:50%/100% no-repeat;display:block}.payplugIntegratedPayment__scheme span:before{width:100%;height:100%;content:"";opacity:0;background:50%/100% no-repeat;display:block}.payplugIntegratedPayment__scheme input{display:none}.payplugIntegratedPayment__scheme input:checked+span:before{opacity:1}.payplugIntegratedPayment__scheme--visa span{background-image:url(visa-dark.87c34e0f.svg)}.payplugIntegratedPayment__scheme--visa span:before{background-image:url(visa.d11a46f6.svg)}.payplugIntegratedPayment__scheme--mastercard span{background-image:url(mastercard-dark.8977e440.svg)}.payplugIntegratedPayment__scheme--mastercard span:before{background-image:url(mastercard.7dd4ce0b.svg)}.payplugIntegratedPayment__scheme--cb span{background-image:url(./cb-dark.888aec45.svg)}.payplugIntegratedPayment__scheme--cb span:before{background-image:url(./cb.ccd964e9.svg)}.payplugIntegratedPayment__error{color:#e91932;width:100%;margin:-10px 0 10px;padding-left:4px;font-size:12px;line-height:18px}.payplugIntegratedPayment__error--cardHolder{margin:-10px 0 0}.payplugIntegratedPayment__error--cvv{justify-self:flex-end;margin:-10px 0 10px auto}.payplugIntegratedPayment__error--exp,.payplugIntegratedPayment__error--cvv{width:100%;max-width:49%}.payplugIntegratedPayment__error--hide{display:none}
\ No newline at end of file
diff --git a/src/Resources/public/assets/shop/lock.fe8a73cd.svg b/assets/shop/dist/payment/lock.fe8a73cd.svg
similarity index 100%
rename from src/Resources/public/assets/shop/lock.fe8a73cd.svg
rename to assets/shop/dist/payment/lock.fe8a73cd.svg
diff --git a/src/Resources/public/assets/shop/mastercard-dark.8977e440.svg b/assets/shop/dist/payment/mastercard-dark.8977e440.svg
similarity index 100%
rename from src/Resources/public/assets/shop/mastercard-dark.8977e440.svg
rename to assets/shop/dist/payment/mastercard-dark.8977e440.svg
diff --git a/src/Resources/public/assets/shop/mastercard.7dd4ce0b.svg b/assets/shop/dist/payment/mastercard.7dd4ce0b.svg
similarity index 100%
rename from src/Resources/public/assets/shop/mastercard.7dd4ce0b.svg
rename to assets/shop/dist/payment/mastercard.7dd4ce0b.svg
diff --git a/src/Resources/public/assets/shop/visa-dark.87c34e0f.svg b/assets/shop/dist/payment/visa-dark.87c34e0f.svg
similarity index 100%
rename from src/Resources/public/assets/shop/visa-dark.87c34e0f.svg
rename to assets/shop/dist/payment/visa-dark.87c34e0f.svg
diff --git a/src/Resources/public/assets/shop/visa.d11a46f6.svg b/assets/shop/dist/payment/visa.d11a46f6.svg
similarity index 100%
rename from src/Resources/public/assets/shop/visa.d11a46f6.svg
rename to assets/shop/dist/payment/visa.d11a46f6.svg
diff --git a/assets/shop/entrypoint.js b/assets/shop/entrypoint.js
new file mode 100644
index 00000000..9ccfccbe
--- /dev/null
+++ b/assets/shop/entrypoint.js
@@ -0,0 +1 @@
+// Mandatory by test application
diff --git a/assets/yarn.lock b/assets/yarn.lock
new file mode 100644
index 00000000..961087b2
--- /dev/null
+++ b/assets/yarn.lock
@@ -0,0 +1,18 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@hotwired/stimulus@^3.0.0":
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
+ integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==
+
+jquery@^3.5.1:
+ version "3.7.1"
+ resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de"
+ integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==
+
+webfontloader@^1.6.28:
+ version "1.6.28"
+ resolved "https://registry.yarnpkg.com/webfontloader/-/webfontloader-1.6.28.tgz#db786129253cb6e8eae54c2fb05f870af6675bae"
+ integrity sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ==
diff --git a/composer.json b/composer.json
old mode 100644
new mode 100755
index e7e66358..079ccdb9
--- a/composer.json
+++ b/composer.json
@@ -4,70 +4,78 @@
"keywords": [
"sylius",
"sylius-plugin",
- "payplug"
+ "payplug",
+ "symfony-ux"
],
"description": "PayPlug payment plugin for Sylius applications.",
"license": "MIT",
"require": {
- "php": "^8.0",
+ "php": "^8.2",
"ext-json": "*",
"giggsey/libphonenumber-for-php": "^8.12",
- "payplug/payplug-php": "^3.1",
+ "payplug/payplug-php": "^4.0",
"php-http/message-factory": "^1.1",
- "sylius/refund-plugin": "^1.4",
- "sylius/sylius": "^1.11.0",
- "symfony/asset": "^4.4|^5.0|^6.0",
- "symfony/lock": "^4.4|^5.0|^6.0",
- "symfony/validator": "^4.4|^5.0|^6.0"
+ "sylius/refund-plugin": "^2.0",
+ "sylius/sylius": "^2.0",
+ "symfony/asset": "^6.4|| ^7.2",
+ "symfony/lock": "^6.4|| ^7.2",
+ "symfony/validator": "^6.4|| ^7.2"
},
"require-dev": {
- "behat/behat": "^3.7",
- "behat/mink-selenium2-driver": "^1.4",
- "dmore/behat-chrome-extension": "^1.3",
- "dmore/chrome-mink-driver": "^2.7",
- "friends-of-behat/mink": "^1.8",
- "friends-of-behat/mink-browserkit-driver": "^1.4",
- "friends-of-behat/mink-debug-extension": "^2.0",
- "friends-of-behat/mink-extension": "^2.4",
- "friends-of-behat/page-object-extension": "^0.3",
- "friends-of-behat/suite-settings-extension": "^1.0",
- "friends-of-behat/symfony-extension": "^2.1",
- "friends-of-behat/variadic-extension": "^1.3",
- "friendsoftwig/twigcs": "^5.0",
- "j13k/yaml-lint": "^1.1",
- "lakion/mink-debug-extension": "^2.0",
- "mockery/mockery": "^1.5",
- "php-parallel-lint/php-parallel-lint": "^1.0",
- "phpmd/phpmd": "^2.8",
- "phpspec/phpspec": "^6.1 || ^7.2",
- "phpstan/extension-installer": "1.1.0",
- "phpstan/phpstan": "1.8.2",
- "phpstan/phpstan-doctrine": "1.3.11",
- "phpstan/phpstan-strict-rules": "1.3.0",
- "phpstan/phpstan-webmozart-assert": "1.2.0",
- "phpunit/phpunit": "^9.0",
- "slevomat/coding-standard": "^6.3.2",
- "sylius-labs/coding-standard": "^4.0",
- "symfony/browser-kit": "^5.0|^6.0",
- "symfony/debug-bundle": "^5.0|^6.0",
- "symfony/dotenv": "^5.0|^6.0",
- "symfony/intl": "^5.0|^6.0",
- "symfony/web-profiler-bundle": "^5.0|^6.0",
+ "behat/behat": "3.20.0",
+ "behat/mink-selenium2-driver": "1.7.0",
+ "dmore/behat-chrome-extension": "1.4.0",
+ "dmore/chrome-mink-driver": "2.9.3",
+ "friends-of-behat/mink": "1.11.0",
+ "friends-of-behat/mink-browserkit-driver": "1.6.2",
+ "friends-of-behat/mink-debug-extension": "2.1.0",
+ "friends-of-behat/mink-extension": "2.7.5",
+ "friends-of-behat/page-object-extension": "0.3.2",
+ "friends-of-behat/suite-settings-extension": "1.1.0",
+ "friends-of-behat/symfony-extension": "2.6.0",
+ "friends-of-behat/variadic-extension": "1.6.0",
+ "friendsoftwig/twigcs": "6.5.0",
+ "lakion/mink-debug-extension": "2.0.0",
+ "mockery/mockery": "1.6.12",
+ "php-parallel-lint/php-parallel-lint": "1.4.0",
+ "phpmd/phpmd": "^2.15.0",
+ "phpro/grumphp": "^2.12",
+ "phpstan/extension-installer": "1.4.3",
+ "phpstan/phpstan": "2.0.4",
+ "phpstan/phpstan-doctrine": "2.0.1",
+ "phpstan/phpstan-strict-rules": "2.0.1",
+ "phpstan/phpstan-webmozart-assert": "2.0.0",
+ "phpunit/phpunit": "9.6.22",
+ "rector/rector": "2.0.4",
+ "sylius-labs/coding-standard": "4.4.0",
+ "sylius/test-application": "^2.1.0@alpha",
+ "symfony/apache-pack": "*",
+ "symfony/browser-kit": "^6.4|| ^7.2",
+ "symfony/debug-bundle": "^6.4|| ^7.2",
+ "symfony/dotenv": "^6.4|| ^7.2",
+ "symfony/web-profiler-bundle": "^6.4|| ^7.2",
"webmozart/assert": "^1.8"
},
"prefer-stable": true,
"autoload": {
"psr-4": {
- "PayPlug\\SyliusPayPlugPlugin\\": "src/",
- "Tests\\PayPlug\\SyliusPayPlugPlugin\\": "tests/"
+ "PayPlug\\SyliusPayPlugPlugin\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\PayPlug\\SyliusPayPlugPlugin\\": ["tests/", "tests/TestApplication/src/"]
}
},
"config": {
"sort-packages": true,
"allow-plugins": {
- "phpstan/extension-installer": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
+ "php-http/discovery": true,
+ "phpro/grumphp": true,
+ "phpstan/extension-installer": true,
"symfony/flex": true,
+ "symfony/runtime": true,
"symfony/thanks": true
}
},
@@ -82,6 +90,26 @@
"@phpmd",
"@phpstan",
"@phpunit"
+ ],
+ "test-application:install": [
+ "vendor/bin/console doctrine:database:drop --force --if-exists -n",
+ "vendor/bin/console doctrine:database:create -n",
+ "vendor/bin/console doctrine:migration:migrate -n",
+ "vendor/bin/console sylius:payment:generate-key -n",
+ "vendor/bin/console sylius:fixtures:load -n",
+ "yarn --cwd vendor/sylius/test-application install",
+ "yarn --cwd vendor/sylius/test-application build",
+ "vendor/bin/console assets:install --symlink -n"
+ ],
+ "test-application:front": [
+ "yarn --cwd vendor/sylius/test-application install --force",
+ "yarn --cwd vendor/sylius/test-application build"
]
+ },
+ "extra": {
+ "public-dir": "vendor/sylius/test-application/public",
+ "symfony": {
+ "require": "^6.4"
+ }
}
}
diff --git a/src/Resources/config/config.yml b/config/config.yml
similarity index 68%
rename from src/Resources/config/config.yml
rename to config/config.yml
index c476d4c2..fb713c19 100644
--- a/src/Resources/config/config.yml
+++ b/config/config.yml
@@ -1,4 +1,4 @@
imports:
- { resource: "state_machine.yml" }
- { resource: "resources.yaml" }
- - { resource: "ui.yaml" }
+ - { resource: "twig_hooks/*.yaml" }
diff --git a/src/Resources/config/resources.yaml b/config/resources.yaml
similarity index 100%
rename from src/Resources/config/resources.yaml
rename to config/resources.yaml
diff --git a/config/routing.yaml b/config/routing.yaml
new file mode 100644
index 00000000..84c98416
--- /dev/null
+++ b/config/routing.yaml
@@ -0,0 +1,6 @@
+payplug_sylius_admin:
+ resource: "@PayPlugSyliusPayPlugPlugin/config/routing/admin.yaml"
+ prefix: '/%sylius_admin.path_name%'
+
+payplug_sylius_shop:
+ resource: "@PayPlugSyliusPayPlugPlugin/config/routing/shop.yaml"
diff --git a/config/routing/admin.yaml b/config/routing/admin.yaml
new file mode 100644
index 00000000..4800b8e9
--- /dev/null
+++ b/config/routing/admin.yaml
@@ -0,0 +1,5 @@
+controllers:
+ resource:
+ path: '../../src/Action/Admin/'
+ namespace: 'PayPlug\SyliusPayPlugPlugin\Action\Admin'
+ type: attribute
\ No newline at end of file
diff --git a/config/routing/shop.yaml b/config/routing/shop.yaml
new file mode 100644
index 00000000..4f34982e
--- /dev/null
+++ b/config/routing/shop.yaml
@@ -0,0 +1,5 @@
+controllers:
+ resource:
+ path: '../../src/Controller/'
+ namespace: 'PayPlug\SyliusPayPlugPlugin\Controller'
+ type: attribute
\ No newline at end of file
diff --git a/config/services.yaml b/config/services.yaml
new file mode 100644
index 00000000..a58fc643
--- /dev/null
+++ b/config/services.yaml
@@ -0,0 +1,139 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+ public: false
+
+ PayPlug\SyliusPayPlugPlugin\:
+ resource: '../src/*'
+ exclude: '../src/{ApiClient,DependencyInjection,Entity,Exception,Model,Repository,PayPlugSyliusPayPlugPlugin.php}'
+ bind:
+ Psr\Log\LoggerInterface: '@monolog.logger.payplug'
+
+ PayPlug\SyliusPayPlugPlugin\Repository\PaymentRepositoryInterface:
+ class: PayPlug\SyliusPayPlugPlugin\Repository\PaymentRepository
+ parent: sylius.repository.payment
+
+ PayPlug\SyliusPayPlugPlugin\Repository\PaymentMethodRepositoryInterface:
+ class: PayPlug\SyliusPayPlugPlugin\Repository\PaymentMethodRepository
+ parent: sylius.repository.payment_method
+
+ PayPlug\SyliusPayPlugPlugin\Controller\OrderController:
+ parent: sylius.controller.order
+
+ PayPlug\SyliusPayPlugPlugin\Provider\OneySimulation\OneySimulationDataProviderInterface:
+ class: PayPlug\SyliusPayPlugPlugin\Provider\OneySimulation\OneySimulationDataProvider
+
+ payplug_sylius_payplug_plugin.action.capture:
+ class: PayPlug\SyliusPayPlugPlugin\Action\CaptureAction
+
+ payplug_sylius_payplug_plugin.action.status:
+ class: PayPlug\SyliusPayPlugPlugin\Action\StatusAction
+
+ payplug_sylius_payplug_plugin.action.convert_payment:
+ class: PayPlug\SyliusPayPlugPlugin\Action\ConvertPaymentAction
+
+ payplug_sylius_payplug_plugin.action.notify:
+ class: PayPlug\SyliusPayPlugPlugin\Action\NotifyAction
+
+ ## Default Payplug Gateway ##
+ payplug_sylius_payplug_plugin.command_provider.payplug:
+ class: Sylius\Bundle\PaymentBundle\CommandProvider\ActionsCommandProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.command_provider.payplug
+ index_by: 'action'
+ tags:
+ - name: sylius.payment_request.command_provider
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\PayPlugGatewayFactory::FACTORY_NAME
+ payplug_sylius_payplug_plugin.provider.order_pay.http_response.payplug:
+ class: Sylius\Bundle\PaymentBundle\Provider\ActionsHttpResponseProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.http_response_provider.payplug
+ index_by: action
+ tags:
+ - name: sylius.payment_request.provider.http_response
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\PayPlugGatewayFactory::FACTORY_NAME
+
+ ## Oney Payplug Gateway ##
+ payplug_sylius_payplug_plugin.command_provider.payplug_oney:
+ class: Sylius\Bundle\PaymentBundle\CommandProvider\ActionsCommandProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.command_provider.payplug_oney
+ index_by: 'action'
+ tags:
+ - name: sylius.payment_request.command_provider
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\OneyGatewayFactory::FACTORY_NAME
+ payplug_sylius_payplug_plugin.provider.order_pay.http_response.payplug_oney:
+ class: Sylius\Bundle\PaymentBundle\Provider\ActionsHttpResponseProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.http_response_provider.payplug_oney
+ index_by: action
+ tags:
+ - name: sylius.payment_request.provider.http_response
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\OneyGatewayFactory::FACTORY_NAME
+
+
+ ## Bancontact Payplug Gateway ##
+ payplug_sylius_payplug_plugin.command_provider.payplug_bancontact:
+ class: Sylius\Bundle\PaymentBundle\CommandProvider\ActionsCommandProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.command_provider.payplug_bancontact
+ index_by: 'action'
+ tags:
+ - name: sylius.payment_request.command_provider
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\BancontactGatewayFactory::FACTORY_NAME
+ payplug_sylius_payplug_plugin.provider.order_pay.http_response.payplug_bancontact:
+ class: Sylius\Bundle\PaymentBundle\Provider\ActionsHttpResponseProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.http_response_provider.payplug_bancontact
+ index_by: action
+ tags:
+ - name: sylius.payment_request.provider.http_response
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\BancontactGatewayFactory::FACTORY_NAME
+
+
+ ## Amex Payplug Gateway ##
+ payplug_sylius_payplug_plugin.command_provider.payplug_american_express:
+ class: Sylius\Bundle\PaymentBundle\CommandProvider\ActionsCommandProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.command_provider.payplug_american_express
+ index_by: 'action'
+ tags:
+ - name: sylius.payment_request.command_provider
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\AmericanExpressGatewayFactory::FACTORY_NAME
+ payplug_sylius_payplug_plugin.provider.order_pay.http_response.payplug_american_express:
+ class: Sylius\Bundle\PaymentBundle\Provider\ActionsHttpResponseProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.http_response_provider.payplug_american_express
+ index_by: action
+ tags:
+ - name: sylius.payment_request.provider.http_response
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\AmericanExpressGatewayFactory::FACTORY_NAME
+
+ ## Apple Pay Payplug Gateway ##
+ payplug_sylius_payplug_plugin.command_provider.payplug_apple_pay:
+ class: Sylius\Bundle\PaymentBundle\CommandProvider\ActionsCommandProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.command_provider.payplug_apple_pay
+ index_by: 'action'
+ tags:
+ - name: sylius.payment_request.command_provider
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\ApplePayGatewayFactory::FACTORY_NAME
+ payplug_sylius_payplug_plugin.provider.order_pay.http_response.payplug_apple_pay:
+ class: Sylius\Bundle\PaymentBundle\Provider\ActionsHttpResponseProvider
+ arguments:
+ - !tagged_locator
+ tag: payplug_sylius_payplug_plugin.http_response_provider.payplug_apple_pay
+ index_by: action
+ tags:
+ - name: sylius.payment_request.provider.http_response
+ gateway_factory: !php/const PayPlug\SyliusPayPlugPlugin\Gateway\ApplePayGatewayFactory::FACTORY_NAME
diff --git a/src/Resources/config/services/client.xml b/config/services/client.xml
similarity index 100%
rename from src/Resources/config/services/client.xml
rename to config/services/client.xml
diff --git a/config/services/gateway.xml b/config/services/gateway.xml
new file mode 100644
index 00000000..eeda89e7
--- /dev/null
+++ b/config/services/gateway.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ PayPlug\SyliusPayPlugPlugin\Gateway\PayPlugGatewayFactory
+
+
+
+
+
+ PayPlug\SyliusPayPlugPlugin\Gateway\OneyGatewayFactory
+
+
+
+
+
+ PayPlug\SyliusPayPlugPlugin\Gateway\BancontactGatewayFactory
+
+
+
+
+
+ PayPlug\SyliusPayPlugPlugin\Gateway\ApplePayGatewayFactory
+
+
+
+
+
+ PayPlug\SyliusPayPlugPlugin\Gateway\AmericanExpressGatewayFactory
+
+
+
+
diff --git a/config/state_machine.yml b/config/state_machine.yml
new file mode 100644
index 00000000..2781aef2
--- /dev/null
+++ b/config/state_machine.yml
@@ -0,0 +1,10 @@
+framework:
+ workflows:
+ !php/const Sylius\Component\Core\OrderPaymentTransitions::GRAPH:
+ transitions:
+ oney_request_payment: # Allow to request payment from authorized (for Oney)
+ from:
+ - cart
+ - authorized
+ to:
+ - awaiting_payment
diff --git a/config/twig_hooks/admin.yaml b/config/twig_hooks/admin.yaml
new file mode 100644
index 00000000..931ecf69
--- /dev/null
+++ b/config/twig_hooks/admin.yaml
@@ -0,0 +1,49 @@
+sylius_twig_hooks:
+ hooks:
+ sylius_admin.payment_method.update.content:
+ payplug_flashes:
+ template: '@PayPlugSyliusPayPlugPlugin/admin/shared/flashes.html.twig'
+ priority: 350
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug': &payplugGateway
+ live_checkbox: &liveCheckbox
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/live_checkbox.html.twig'
+ priority: 0
+ one_click:
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/one_click.html.twig'
+ priority: 0
+ integrated_payment:
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/integrated_payment.html.twig'
+ priority: 0
+ deferred_capture:
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/deferred_capture.html.twig'
+ priority: 0
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_oney': &oneyGateway
+ live_checkbox: *liveCheckbox
+ fees_for:
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/fees_for.html.twig'
+ priority: 0
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_bancontact': &bancontactGateway
+ live_checkbox: *liveCheckbox
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_apple_pay': &applePayGateway
+ live_checkbox: *liveCheckbox
+
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_american_express': &amexGateway
+ live_checkbox: *liveCheckbox
+
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug':
+ <<: *payplugGateway
+ renew_oauth: &renewOAuth
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/renew_oauth.html.twig'
+ priority: -5
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_oney':
+ <<: *oneyGateway
+ renew_oauth: *renewOAuth
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_bancontact':
+ <<: *bancontactGateway
+ renew_oauth: *renewOAuth
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_apple_pay':
+ <<: *applePayGateway
+ renew_oauth: *renewOAuth
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_american_express':
+ <<: *amexGateway
+ renew_oauth: *renewOAuth
diff --git a/config/twig_hooks/shop.yaml b/config/twig_hooks/shop.yaml
new file mode 100644
index 00000000..ed250d5f
--- /dev/null
+++ b/config/twig_hooks/shop.yaml
@@ -0,0 +1,46 @@
+sylius_twig_hooks:
+ hooks:
+ 'sylius_shop.product.show.content.info.summary':
+ pay_with_oney:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/oney/product/pay_with_oney.html.twig'
+ priority: 101
+ 'sylius_shop.cart.index.content.form.sections.general#right':
+ pay_with_oney:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/oney/cart/pay_with_oney.html.twig'
+ priority: 1
+ 'sylius.shop.account.saved_cards.index.subcontent':
+ header:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/saved_cards/index/_header.html.twig'
+ priority: 20
+ subcontent:
+ template: "@PayPlugSyliusPayPlugPlugin/shop/saved_cards/index/_subcontent.html.twig"
+ priority: 10
+
+ 'sylius_shop.checkout.select_payment':
+ modal:
+ template: '@PayPlugSyliusPayPlugPlugin/shared/modal/index.html.twig'
+ priority: 0
+
+ 'sylius_shop.shared.form.select_payment.payment':
+ choice:
+ template: '@PayPlugSyliusPayPlugPlugin/shared/form/select_payment/payment/choice.html.twig'
+ priority: 0
+
+ 'sylius_shop.shared.form.select_payment.payment.choice.details':
+ choice:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/choice.html.twig'
+ 'sylius_shop.shared.form.select_payment.payment.choice.details#payplug':
+ payplug:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/_payplug.html.twig'
+ 'sylius_shop.shared.form.select_payment.payment.choice.details#payplug_oney':
+ oney:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/_oney.html.twig'
+ 'sylius_shop.shared.form.select_payment.payment.choice.details#payplug_bancontact':
+ bancontact:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/_bancontact.html.twig'
+ 'sylius_shop.shared.form.select_payment.payment.choice.details#payplug_apple_pay':
+ apple_pay:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/_apple_pay.html.twig'
+ 'sylius_shop.shared.form.select_payment.payment.choice.details#payplug_american_express':
+ american_express:
+ template: '@PayPlugSyliusPayPlugPlugin/shop/select_payment/_american_express.html.twig'
diff --git a/doc/authorized_payment.md b/doc/authorized_payment.md
index c682cfa0..83332706 100644
--- a/doc/authorized_payment.md
+++ b/doc/authorized_payment.md
@@ -46,6 +46,8 @@ winzou_state_machine:
> [!NOTE]
> This configuration is already added by the plugin.
+### With Winzou State Machine
+
For example, if you want to trigger the capture when an order is shipped, you can create a callback on the `sylius_order_shipping` state machine.
File: `config/packages/winzou_state_machine.yaml`
@@ -99,3 +101,55 @@ class CaptureOrderProcessor
}
}
```
+
+### With Symfony Workflow (default in Sylius 2)
+
+If you are using Symfony Workflow, you can create a custom action to capture the payment, with a transition listener.
+
+File: `src/StateMachine/CaptureOrderProcessor.php`
+
+```php
+getSubject();
+ if (!$order instanceof OrderInterface) {
+ throw new \LogicException('Expected an instance of OrderInterface');
+ }
+
+ $payment = $order->getLastPayment(PaymentInterface::STATE_AUTHORIZED);
+ if (null === $payment) {
+ // No payment in authorized state, nothing to do here
+ return;
+ }
+
+ $this->stateMachine->apply($payment, PaymentTransitions::GRAPH, PaymentTransitions::TRANSITION_COMPLETE);
+ if (PaymentInterface::STATE_COMPLETED !== $payment->getState()) {
+ throw new \LogicException('Oh no! Payment capture failed 💸');
+ }
+ }
+}
+```
diff --git a/doc/development.md b/doc/development.md
index 49ab58b7..ab362af8 100644
--- a/doc/development.md
+++ b/doc/development.md
@@ -3,13 +3,11 @@
## Assets
For the sake of quickness, the usage of a tool like [Parcel](https://github.com/parcel-bundler/parcel/tree/1.x) shows that its efficiency is indeed undeniable.
-
-So, if you want to edit assets (js, scss, ...) you'll likely go into `src/Resources/dev` and run `yarn install`.
-
+So, if you want to edit assets (js, scss, ...) you'll likely go into `assets` and run `yarn install`.
Then, you'll find a list of commands inside `package.json` which are :
```bash
-$ (cd src/Resources/dev && yarn build)
+$ (cd assets && yarn build)
```
Or, if you prefer the dev mode; a `watch` command that compile in real time, then run:
@@ -18,9 +16,10 @@ Or, if you prefer the dev mode; a `watch` command that compile in real time, the
$ (cd src/Resources/dev && yarn dev)
```
-You can add any resources as far as Parcel can go, but those have to be located in `/pages` otherwize they won't be compiled.
+You can add any resources as far as Parcel can go,
+but those have to be located in `/pages` otherwise they won't be compiled.
-Assets can be found in `src/Resources/public/assets/oney` so you'll have to install them in your application by running:
+Assets can be found in `public/assets/oney` so you'll have to install them in your application by running:
```bash
$ bin/console assets:install --symlink
@@ -28,7 +27,8 @@ $ bin/console assets:install --symlink
$ bin/console sylius:theme:assets:install --symlink # e.g if bootstrapTheme is enabled
```
-To make it fully compatible with [Sylius Bootstrap Theme](https://github.com/Sylius/BootstrapTheme), some lines have to be added to ̀the main entrypoint (such as `app.js`) of the theme:
+To make it fully compatible with [Sylius Bootstrap Theme](https://github.com/Sylius/BootstrapTheme),
+some lines have to be added to the main entrypoint (such as `app.js`) of the theme:
```js
const $ = require('jquery');
diff --git a/grumphp.yml b/grumphp.yml
new file mode 100644
index 00000000..1ae601d8
--- /dev/null
+++ b/grumphp.yml
@@ -0,0 +1,32 @@
+grumphp:
+ ascii:
+ failed: ~
+ succeeded: ~
+ tasks:
+ composer:
+ no_check_all: true
+ jsonlint:
+ detect_key_conflicts: true
+ phplint:
+ exclude: ['vendor', 'tests/Application/*']
+ triggered_by: ['php']
+ phpstan:
+ level: ~
+ configuration: 'ruleset/phpstan.neon'
+ use_grumphp_paths: false
+ securitychecker_symfony: ~
+ yamllint:
+ parse_custom_tags: true
+ ecs:
+ config: 'ruleset/ecs.php'
+ no-progress-bar: true
+ twigcs:
+ path: 'src/'
+ severity: error
+ phpcs:
+ standard: "ruleset"
+ warning_severity: 0
+ whitelist_patterns:
+ - 'src'
+ exclude:
+ - 'PSR12.Files.FileHeader'
\ No newline at end of file
diff --git a/install/Application/.gitignore b/install/Application/.gitignore
deleted file mode 100644
index 83c72082..00000000
--- a/install/Application/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.env.*.local
-.env.local
-.env.local.php
diff --git a/install/Application/config/packages/payplug.yaml b/install/Application/config/packages/payplug.yaml
deleted file mode 100644
index 1d41d8b4..00000000
--- a/install/Application/config/packages/payplug.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-parameters:
- sylius_refund.supported_gateways:
- - payplug
- - payplug_oney
- - cash_on_delivery
-
-services:
- payplug_sylius_payplug_plugin.api_client.payplug:
- class: Tests\PayPlug\SyliusPayPlugPlugin\Behat\Mocker\PayPlugApiClient
- public: true
- arguments:
- - "@service_container"
- - 'payplug_sylius_payplug_plugin.api_client.payplug'
-
- payplug_sylius_payplug_plugin.api_client.oney:
- class: Tests\PayPlug\SyliusPayPlugPlugin\Behat\Mocker\PayPlugApiClient
- public: true
- arguments:
- - "@service_container"
- - 'payplug_sylius_payplug_plugin.api_client.oney'
-
- Tests\Sylius\RefundPlugin\Behat\Services\Generator\FailedCreditMemoGenerator:
- decorates: 'Sylius\RefundPlugin\Generator\CreditMemoGeneratorInterface'
- arguments:
- - '@Tests\Sylius\RefundPlugin\Behat\Services\Generator\FailedCreditMemoGenerator.inner'
-
- Tests\Sylius\RefundPlugin\Behat\Services\Factory\FailedRefundPaymentFactory:
- decorates: 'sylius_refund.factory.refund_payment'
- arguments:
- - '@Tests\Sylius\RefundPlugin\Behat\Services\Factory\FailedRefundPaymentFactory.inner'
diff --git a/install/Application/config/packages/sylius_payplug.yaml b/install/Application/config/packages/sylius_payplug.yaml
deleted file mode 100644
index 82462ec0..00000000
--- a/install/Application/config/packages/sylius_payplug.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-imports:
- - { resource: "@PayPlugSyliusPayPlugPlugin/Resources/config/config.yml" }
- - { resource: "@PayPlugSyliusPayPlugPlugin/Resources/config/services.xml" }
diff --git a/install/Application/config/packages/sylius_refund.yaml b/install/Application/config/packages/sylius_refund.yaml
deleted file mode 100644
index ce7ff8ae..00000000
--- a/install/Application/config/packages/sylius_refund.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - { resource: "@SyliusRefundPlugin/Resources/config/app/config.yml" }
diff --git a/install/Application/config/routes/payplug.yaml b/install/Application/config/routes/payplug.yaml
deleted file mode 100644
index 778bf549..00000000
--- a/install/Application/config/routes/payplug.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-sylius_payplug:
- resource: "@PayPlugSyliusPayPlugPlugin/Resources/config/routing.yaml"
diff --git a/install/Application/config/routes/sylius_refund.yaml b/install/Application/config/routes/sylius_refund.yaml
deleted file mode 100755
index 46e99b16..00000000
--- a/install/Application/config/routes/sylius_refund.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-sylius_refund:
- resource: "@SyliusRefundPlugin/Resources/config/routing.yml"
diff --git a/install/Application/config/services_payplug.yaml b/install/Application/config/services_payplug.yaml
deleted file mode 100644
index e7c39ea2..00000000
--- a/install/Application/config/services_payplug.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-parameters:
- sylius_refund.supported_gateways:
- - payplug
- - payplug_oney
- - cash_on_delivery
-
-services:
- payplug_sylius_payplug_plugin.api_client.payplug:
- class: Tests\PayPlug\SyliusPayPlugPlugin\Behat\Mocker\PayPlugApiClient
- public: true
- arguments:
- - "@service_container"
- - 'payplug_sylius_payplug_plugin.api_client.payplug'
-
- payplug_sylius_payplug_plugin.api_client.oney:
- class: Tests\PayPlug\SyliusPayPlugPlugin\Behat\Mocker\PayPlugApiClient
- public: true
- arguments:
- - "@service_container"
- - 'payplug_sylius_payplug_plugin.api_client.oney'
-
- PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClientFactoryInterface:
- class: Tests\PayPlug\SyliusPayPlugPlugin\Behat\Mocker\PayPlugApiClientFactory
- public: true
- arguments:
- - "@service_container"
- - "payplug_sylius_payplug_plugin.api_client.payplug"
-
- Tests\Sylius\RefundPlugin\Behat\Services\Generator\FailedCreditMemoGenerator:
- decorates: 'Sylius\RefundPlugin\Generator\CreditMemoGeneratorInterface'
- arguments:
- - '@Tests\Sylius\RefundPlugin\Behat\Services\Generator\FailedCreditMemoGenerator.inner'
-
- Tests\Sylius\RefundPlugin\Behat\Services\Factory\FailedRefundPaymentFactory:
- decorates: 'sylius_refund.factory.refund_payment'
- arguments:
- - '@Tests\Sylius\RefundPlugin\Behat\Services\Factory\FailedRefundPaymentFactory.inner'
diff --git a/src/Migrations/Version20210410143918.php b/migrations/Version20210410143918.php
similarity index 100%
rename from src/Migrations/Version20210410143918.php
rename to migrations/Version20210410143918.php
diff --git a/src/Migrations/Version20210823123914.php b/migrations/Version20210823123914.php
similarity index 100%
rename from src/Migrations/Version20210823123914.php
rename to migrations/Version20210823123914.php
diff --git a/phpspec.yml.dist b/phpspec.yml.dist
deleted file mode 100644
index cdbf5061..00000000
--- a/phpspec.yml.dist
+++ /dev/null
@@ -1,4 +0,0 @@
-suites:
- main:
- namespace: PayPlug\SyliusPayPlugPlugin
- psr4_prefix: PayPlug\SyliusPayPlugPlugin
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 8e5a0339..b01264ac 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,19 +1,18 @@
+ bootstrap="vendor/sylius/test-application/config/bootstrap.php">
- vendor/payplug/sylius-payplug-plugin/tests/PHPUnit
+ tests/PHPUnit
-
-
+
diff --git a/src/Resources/public/assets/american-express/logo.svg b/public/assets/american-express/logo.svg
similarity index 98%
rename from src/Resources/public/assets/american-express/logo.svg
rename to public/assets/american-express/logo.svg
index 402f9f52..5a587766 100644
--- a/src/Resources/public/assets/american-express/logo.svg
+++ b/public/assets/american-express/logo.svg
@@ -1,25 +1,25 @@
-
-
-
+
+
+
diff --git a/src/Resources/public/assets/apple-pay/logo.svg b/public/assets/apple-pay/logo.svg
similarity index 100%
rename from src/Resources/public/assets/apple-pay/logo.svg
rename to public/assets/apple-pay/logo.svg
diff --git a/src/Resources/public/assets/bancontact/logo.svg b/public/assets/bancontact/logo.svg
similarity index 100%
rename from src/Resources/public/assets/bancontact/logo.svg
rename to public/assets/bancontact/logo.svg
diff --git a/src/Resources/public/assets/oney/3x.svg b/public/assets/oney/3x.svg
similarity index 100%
rename from src/Resources/public/assets/oney/3x.svg
rename to public/assets/oney/3x.svg
diff --git a/src/Resources/public/assets/oney/3x4x-alt.svg b/public/assets/oney/3x4x-alt.svg
similarity index 100%
rename from src/Resources/public/assets/oney/3x4x-alt.svg
rename to public/assets/oney/3x4x-alt.svg
diff --git a/src/Resources/public/assets/oney/3x4x-without-fees-alt.svg b/public/assets/oney/3x4x-without-fees-alt.svg
similarity index 100%
rename from src/Resources/public/assets/oney/3x4x-without-fees-alt.svg
rename to public/assets/oney/3x4x-without-fees-alt.svg
diff --git a/src/Resources/public/assets/oney/3x4x-without-fees.svg b/public/assets/oney/3x4x-without-fees.svg
similarity index 100%
rename from src/Resources/public/assets/oney/3x4x-without-fees.svg
rename to public/assets/oney/3x4x-without-fees.svg
diff --git a/src/Resources/public/assets/oney/3x4x.svg b/public/assets/oney/3x4x.svg
similarity index 100%
rename from src/Resources/public/assets/oney/3x4x.svg
rename to public/assets/oney/3x4x.svg
diff --git a/src/Resources/public/assets/oney/4x.svg b/public/assets/oney/4x.svg
similarity index 100%
rename from src/Resources/public/assets/oney/4x.svg
rename to public/assets/oney/4x.svg
diff --git a/src/Resources/public/assets/oney/logo.svg b/public/assets/oney/logo.svg
similarity index 100%
rename from src/Resources/public/assets/oney/logo.svg
rename to public/assets/oney/logo.svg
diff --git a/src/Resources/public/assets/oney/oney_x3_with_fees.svg b/public/assets/oney/oney_x3_with_fees.svg
similarity index 100%
rename from src/Resources/public/assets/oney/oney_x3_with_fees.svg
rename to public/assets/oney/oney_x3_with_fees.svg
diff --git a/src/Resources/public/assets/oney/oney_x3_without_fees.svg b/public/assets/oney/oney_x3_without_fees.svg
similarity index 100%
rename from src/Resources/public/assets/oney/oney_x3_without_fees.svg
rename to public/assets/oney/oney_x3_without_fees.svg
diff --git a/src/Resources/public/assets/oney/oney_x4_with_fees.svg b/public/assets/oney/oney_x4_with_fees.svg
similarity index 100%
rename from src/Resources/public/assets/oney/oney_x4_with_fees.svg
rename to public/assets/oney/oney_x4_with_fees.svg
diff --git a/src/Resources/public/assets/oney/oney_x4_without_fees.svg b/public/assets/oney/oney_x4_without_fees.svg
similarity index 100%
rename from src/Resources/public/assets/oney/oney_x4_without_fees.svg
rename to public/assets/oney/oney_x4_without_fees.svg
diff --git a/src/Resources/public/assets/shop/images/integrated/lock.svg b/public/assets/shop/images/integrated/lock.svg
similarity index 100%
rename from src/Resources/public/assets/shop/images/integrated/lock.svg
rename to public/assets/shop/images/integrated/lock.svg
diff --git a/src/Resources/public/assets/shop/images/integrated/logo-payplug.png b/public/assets/shop/images/integrated/logo-payplug.png
similarity index 100%
rename from src/Resources/public/assets/shop/images/integrated/logo-payplug.png
rename to public/assets/shop/images/integrated/logo-payplug.png
diff --git a/rulesets/.php_md.xml b/ruleset/.php_md.xml
similarity index 100%
rename from rulesets/.php_md.xml
rename to ruleset/.php_md.xml
diff --git a/ruleset/ecs.php b/ruleset/ecs.php
new file mode 100644
index 00000000..7de9449a
--- /dev/null
+++ b/ruleset/ecs.php
@@ -0,0 +1,19 @@
+import(dirname(__DIR__) . '/vendor/sylius-labs/coding-standard/ecs.php');
+
+ $ecsConfig->paths([
+ dirname(__DIR__, 1) . '/src',
+ dirname(__DIR__, 1) . '/tests/Behat',
+ dirname(__DIR__, 1) . '/tests/PHPUnit',
+ ]);
+
+ /** @phpstan-ignore-next-line */
+ $ecsConfig->rule(\SlevomatCodingStandard\Sniffs\Classes\RequireMultiLineMethodSignatureSniff::class);
+ $ecsConfig->skip([\PhpCsFixer\Fixer\Basic\BracesFixer::class]);
+};
diff --git a/ruleset/phpstan-baseline.neon b/ruleset/phpstan-baseline.neon
new file mode 100644
index 00000000..2ed4e7ab
--- /dev/null
+++ b/ruleset/phpstan-baseline.neon
@@ -0,0 +1,1469 @@
+parameters:
+ ignoreErrors:
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Action/Admin/CompleteRefundPaymentAction.php
+
+ -
+ message: '#^Parameter \#1 \$id of class Sylius\\RefundPlugin\\Event\\RefundPaymentGenerated constructor expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/Admin/CompleteRefundPaymentAction.php
+
+ -
+ message: '#^Parameter \#5 \$paymentMethodId of class Sylius\\RefundPlugin\\Event\\RefundPaymentGenerated constructor expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/Admin/CompleteRefundPaymentAction.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 3
+ path: ../src/Action/Admin/RefundUnitsAction.php
+
+ -
+ message: '#^Cannot access offset ''billing'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot access offset ''can_save_cards'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot access offset ''cancel_url'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot access offset ''postcode'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 6
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot access offset ''shipping'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot access property \$payment_url on mixed\.$#'
+ identifier: property.nonObject
+ count: 2
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 6
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot call method getFirstModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot call method getModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot call method getToken\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Parameter \#1 \$timestamp of method DateTimeImmutable\:\:setTimestamp\(\) expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Parameter \#1 \$url of class Payum\\Core\\Reply\\HttpRedirect constructor expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 3
+ path: ../src/Action/CaptureAction.php
+
+ -
+ message: '#^Cannot call method getSource\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/ConvertPaymentAction.php
+
+ -
+ message: '#^Cannot call method setResult\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/ConvertPaymentAction.php
+
+ -
+ message: '#^Cannot call method getFirstModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Action/NotifyAction.php
+
+ -
+ message: '#^Cannot call method getModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/NotifyAction.php
+
+ -
+ message: '#^Parameter \#1 \$payment of method PayPlug\\SyliusPayPlugPlugin\\Handler\\PaymentNotificationHandler\:\:treat\(\) expects Sylius\\Component\\Core\\Model\\PaymentInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/NotifyAction.php
+
+ -
+ message: '#^Parameter \#1 \$payment of method PayPlug\\SyliusPayPlugPlugin\\Handler\\RefundNotificationHandler\:\:treat\(\) expects Sylius\\Component\\Core\\Model\\PaymentInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/NotifyAction.php
+
+ -
+ message: '#^Access to an undefined property PayPlug\\SyliusPayPlugPlugin\\Action\\StatusAction\:\:\$stateMachineFactory\.$#'
+ identifier: property.notFound
+ count: 2
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method apply\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method can\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method get\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method getFirstModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 3
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method getModel\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Cannot call method markNew\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Parameter \#1 \$payment of method PayPlug\\SyliusPayPlugPlugin\\Handler\\PaymentNotificationHandler\:\:treat\(\) expects Sylius\\Component\\Core\\Model\\PaymentInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 3
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Parameter \#1 \$payment of method PayPlug\\SyliusPayPlugPlugin\\PaymentProcessing\\RefundPaymentHandlerInterface\:\:updatePaymentStatus\(\) expects Sylius\\Component\\Core\\Model\\PaymentInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Parameter \#1 \$paymentId of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientInterface\:\:retrieve\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 3
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Parameter \#1 \$status of method PayPlug\\SyliusPayPlugPlugin\\Action\\StatusAction\:\:markRequestAs\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Parameter \#2 \$request of method PayPlug\\SyliusPayPlugPlugin\\Action\\StatusAction\:\:markRequestAs\(\) expects Payum\\Core\\Request\\GetStatusInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Action/StatusAction.php
+
+ -
+ message: '#^Access to constant VERSION on an unknown class Sylius\\Bundle\\CoreBundle\\Application\\Kernel\.$#'
+ identifier: class.notFound
+ count: 2
+ path: ../src/ApiClient/PayPlugApiClient.php
+
+ -
+ message: '#^Anonymous function should return array but returns mixed\.$#'
+ identifier: return.type
+ count: 1
+ path: ../src/ApiClient/PayPlugApiClient.php
+
+ -
+ message: '#^Binary operation "\." between ''Sylius/'' and mixed results in an error\.$#'
+ identifier: binaryOp.invalid
+ count: 2
+ path: ../src/ApiClient/PayPlugApiClient.php
+
+ -
+ message: '#^PHPDoc tag @var with type Payplug\\Resource\\Refund\|null is not subtype of type Payplug\\Refund\|null\.$#'
+ identifier: varTag.type
+ count: 2
+ path: ../src/ApiClient/PayPlugApiClient.php
+
+ -
+ message: '#^PHPDoc tag @var with type Payum\\Core\\Model\\GatewayConfig\|null is not subtype of type Sylius\\Resource\\Model\\ResourceInterface\|null\.$#'
+ identifier: varTag.type
+ count: 1
+ path: ../src/ApiClient/PayPlugApiClientFactory.php
+
+ -
+ message: '#^Parameter \#1 \$secretKey of class PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClient constructor expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 2
+ path: ../src/ApiClient/PayPlugApiClientFactory.php
+
+ -
+ message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#'
+ identifier: foreach.nonIterable
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Cannot access offset ''enabled'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Cannot call method getHostname\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\Checker\\CanSavePayplugPaymentMethodChecker\:\:isEnabled\(\) should return bool but returns mixed\.$#'
+ identifier: return.type
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Parameter \#1 \$method of method PayPlug\\SyliusPayPlugPlugin\\Checker\\CanSavePayplugPaymentMethodChecker\:\:isAllowedDomainNames\(\) expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Parameter \#2 \$haystack of function in_array expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Checker/CanSavePayplugPaymentMethodChecker.php
+
+ -
+ message: '#^Cannot access offset ''allowed_countries'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Cannot access offset ''max_amounts'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Cannot access offset ''min_amounts'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Cannot access offset ''oney'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 3
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Cannot access offset string on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Parameter \#2 \$haystack of function in_array expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Checker/OneyChecker.php
+
+ -
+ message: '#^Cannot call method apply\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Command/CaptureAuthorizedPaymentCommand.php
+
+ -
+ message: '#^Cannot call method get\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Command/CaptureAuthorizedPaymentCommand.php
+
+ -
+ message: '#^Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Command/CaptureAuthorizedPaymentCommand.php
+
+ -
+ message: '#^Property PayPlug\\SyliusPayPlugPlugin\\Command\\CaptureAuthorizedPaymentCommand\:\:\$stateMachineFactory has no type specified\.$#'
+ identifier: missingType.property
+ count: 1
+ path: ../src/Command/CaptureAuthorizedPaymentCommand.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Controller/CardController.php
+
+ -
+ message: '#^Parameter \#2 \$type of method Symfony\\Component\\Form\\FormBuilderInterface\:\:add\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/CompleteInfoController.php
+
+ -
+ message: '#^PHPDoc tag @param for parameter \$paymentMethodRepository contains generic type Sylius\\Component\\Resource\\Repository\\RepositoryInterface\ but interface Sylius\\Component\\Resource\\Repository\\RepositoryInterface is not generic\.$#'
+ identifier: generics.notGeneric
+ count: 1
+ path: ../src/Controller/IntegratedPaymentController.php
+
+ -
+ message: '#^PHPDoc type for property PayPlug\\SyliusPayPlugPlugin\\Controller\\IntegratedPaymentController\:\:\$paymentMethodRepository contains generic type Sylius\\Component\\Resource\\Repository\\RepositoryInterface\ but interface Sylius\\Component\\Resource\\Repository\\RepositoryInterface is not generic\.$#'
+ identifier: generics.notGeneric
+ count: 1
+ path: ../src/Controller/IntegratedPaymentController.php
+
+ -
+ message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#'
+ identifier: function.alreadyNarrowedType
+ count: 1
+ path: ../src/Controller/IpnAction.php
+
+ -
+ message: '#^Parameter \#1 \$payplugPaymentId of method PayPlug\\SyliusPayPlugPlugin\\Repository\\PaymentRepositoryInterface\:\:findOneByPayPlugPaymentId\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/IpnAction.php
+
+ -
+ message: '#^Parameter \#1 \$secretKey of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientInterface\:\:initialise\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/IpnAction.php
+
+ -
+ message: '#^Parameter \#2 \$key of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientFactoryInterface\:\:create\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/IpnAction.php
+
+ -
+ message: '#^Cannot access offset ''payment_url'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^Cannot access offset ''return_url'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^Cannot cast mixed to string\.$#'
+ identifier: cast.string
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^PHPDoc tag @var with type Payum\\Core\\Model\\GatewayConfigInterface is not subtype of type Sylius\\Component\\Payment\\Model\\GatewayConfigInterface\|null\.$#'
+ identifier: varTag.type
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^Parameter \#1 \$url of class Symfony\\Component\\HttpFoundation\\RedirectResponse constructor expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^Parameter \#2 \$key of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientFactory\:\:create\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/OneClickAction.php
+
+ -
+ message: '#^Cannot cast mixed to int\.$#'
+ identifier: cast.int
+ count: 1
+ path: ../src/Controller/OneyIsProductEligible.php
+
+ -
+ message: '#^PHPDoc tag @var with type int\|null is not subtype of native type int\.$#'
+ identifier: varTag.nativeType
+ count: 1
+ path: ../src/Controller/OneyIsProductEligible.php
+
+ -
+ message: '#^Parameter \#2 \$productVariantCode of method PayPlug\\SyliusPayPlugPlugin\\Controller\\OneyIsProductEligible\:\:isProductEligible\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Controller/OneyIsProductEligible.php
+
+ -
+ message: '#^Cannot cast mixed to int\.$#'
+ identifier: cast.int
+ count: 1
+ path: ../src/Controller/OneySimulationPopin.php
+
+ -
+ message: '#^PHPDoc tag @var with type int\|null is not subtype of native type int\.$#'
+ identifier: varTag.nativeType
+ count: 1
+ path: ../src/Controller/OneySimulationPopin.php
+
+ -
+ message: '#^Binary operation "\." between ''apple_pay_cancel'' and mixed results in an error\.$#'
+ identifier: binaryOp.invalid
+ count: 1
+ path: ../src/Controller/OrderController.php
+
+ # Session Specific
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 4
+ path: ../src/Controller/OrderController.php
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Action/Admin/Auth/UnifiedAuthenticationController.php
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Validator/PaymentMethodValidator.php
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/EventListener/PostSavePaymentMethodEventListener.php
+
+ -
+ message: '#^Cannot call method apply\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 3
+ path: ../src/Controller/OrderController.php
+
+ -
+ message: '#^Cannot call method can\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 3
+ path: ../src/Controller/OrderController.php
+
+ -
+ message: '#^Cannot call method get\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 3
+ path: ../src/Controller/OrderController.php
+
+ -
+ message: '#^Property PayPlug\\SyliusPayPlugPlugin\\Controller\\OrderController\:\:\$stateMachineFactory has no type specified\.$#'
+ identifier: missingType.property
+ count: 1
+ path: ../src/Controller/OrderController.php
+
+ -
+ message: '#^Cannot access offset ''company_name'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Cannot access offset ''first_name'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Cannot access offset ''last_name'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 2
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^PHPDoc tag @SuppressWarnings has invalid value \(\(PHPMD\.UnusedFormalParameter\)\)\: Unexpected token "\.UnusedFormalParameter\)", expected ''\)'' at offset 34 on line 2$#'
+ identifier: phpDoc.parseError
+ count: 1
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 2
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Parameter \#3 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 2
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Parameter &\$landingPhone by\-ref type of method PayPlug\\SyliusPayPlugPlugin\\Creator\\PayPlugPaymentDataCreator\:\:loadPhoneNumbers\(\) expects string\|null, mixed given\.$#'
+ identifier: parameterByRef.type
+ count: 1
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Parameter &\$mobilePhone by\-ref type of method PayPlug\\SyliusPayPlugPlugin\\Creator\\PayPlugPaymentDataCreator\:\:loadPhoneNumbers\(\) expects string\|null, mixed given\.$#'
+ identifier: parameterByRef.type
+ count: 1
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^Right side of && is always true\.$#'
+ identifier: booleanAnd.rightAlwaysTrue
+ count: 1
+ path: ../src/Creator/PayPlugPaymentDataCreator.php
+
+ -
+ message: '#^PHPDoc tag @var with type Payum\\Core\\Model\\GatewayConfigInterface is not subtype of type Sylius\\Component\\Payment\\Model\\GatewayConfigInterface\|null\.$#'
+ identifier: varTag.type
+ count: 1
+ path: ../src/Creator/RefundUnitsCommandCreatorDecorator.php
+
+ -
+ message: '#^Parameter \#1 \$paymentId of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientInterface\:\:retrieve\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Creator/RefundUnitsCommandCreatorDecorator.php
+
+ -
+ message: '#^Parameter \#1 \$unit of method PayPlug\\SyliusPayPlugPlugin\\Creator\\RefundUnitsCommandCreatorDecorator\:\:getAmount\(\) expects Sylius\\RefundPlugin\\Model\\UnitRefundInterface, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Creator/RefundUnitsCommandCreatorDecorator.php
+
+ -
+ message: '#^Parameter \#1 \$units of method Sylius\\RefundPlugin\\Converter\\RefundUnitsConverterInterface\:\:convert\(\) expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 2
+ path: ../src/Creator/RefundUnitsCommandCreatorDecorator.php
+
+ -
+ message: '#^Property PayPlug\\SyliusPayPlugPlugin\\Entity\\RefundHistory\:\:\$value type mapping mismatch\: database can contain int\|null but property expects int\.$#'
+ identifier: doctrine.columnType
+ count: 1
+ path: ../src/Entity/RefundHistory.php
+
+ -
+ message: '#^Trait PayPlug\\SyliusPayPlugPlugin\\Entity\\Traits\\CustomerTrait is used zero times and is not analysed\.$#'
+ identifier: trait.unused
+ count: 1
+ path: ../src/Entity/Traits/CustomerTrait.php
+
+ -
+ message: '#^Trait PayPlug\\SyliusPayPlugPlugin\\Entity\\Traits\\PaymentMethodTrait is used zero times and is not analysed\.$#'
+ identifier: trait.unused
+ count: 1
+ path: ../src/Entity/Traits/PaymentMethodTrait.php
+
+ -
+ message: '#^Trait PayPlug\\SyliusPayPlugPlugin\\Entity\\Traits\\PaymentTrait is used zero times and is not analysed\.$#'
+ identifier: trait.unused
+ count: 1
+ path: ../src/Entity/Traits/PaymentTrait.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/EventSubscriber/DisplayOneyGatewayFormEventSubscriber.php
+
+ -
+ message: '#^Cannot call method apply\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/EventSubscriber/PostPaymentSelectEventSubscriber.php
+
+ -
+ message: '#^Cannot call method can\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/EventSubscriber/PostPaymentSelectEventSubscriber.php
+
+ -
+ message: '#^Cannot call method get\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/EventSubscriber/PostPaymentSelectEventSubscriber.php
+
+ -
+ message: '#^Property PayPlug\\SyliusPayPlugPlugin\\EventSubscriber\\PostPaymentSelectEventSubscriber\:\:\$stateMachineFactory has no type specified\.$#'
+ identifier: missingType.property
+ count: 1
+ path: ../src/EventSubscriber/PostPaymentSelectEventSubscriber.php
+
+ -
+ message: '#^Parameter \#1 \$input of method Payum\\Core\\Bridge\\Spl\\ArrayObject\:\:defaults\(\) expects array\|Traversable, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/AbstractGatewayFactory.php
+
+ -
+ message: '#^Parameter \#1 \$required of method Payum\\Core\\Bridge\\Spl\\ArrayObject\:\:validateNotEmpty\(\) expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/AbstractGatewayFactory.php
+
+ -
+ message: '#^Parameter \#1 \$secretKey of class PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClient constructor expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/AbstractGatewayFactory.php
+
+ -
+ message: '#^Parameter \#2 \$factoryName of class PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClient constructor expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/AbstractGatewayFactory.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Form/Type/AbstractGatewayConfigurationType.php
+
+ -
+ message: '#^Cannot call method getId\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Form/Type/AbstractGatewayConfigurationType.php
+
+ -
+ message: '#^Cannot access offset ''secretKey'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Cannot call method getConfig\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Cannot call method getData\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Cannot call method getGatewayConfig\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\Gateway\\Validator\\Constraints\\IsCanSaveCardsValidator\:\:validate\(\) has parameter \$value with no type specified\.$#'
+ identifier: missingType.parameter
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Parameter \#2 \$key of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientFactory\:\:create\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSaveCardsValidator.php
+
+ -
+ message: '#^Cannot call method getChannels\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Cannot call method getData\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Cannot call method getFactoryName\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Cannot call method getGatewayConfig\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\Gateway\\Validator\\Constraints\\IsCanSavePaymentMethodValidator\:\:validate\(\) has parameter \$value with no type specified\.$#'
+ identifier: missingType.parameter
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Parameter \#2 \$channels of method PayPlug\\SyliusPayPlugPlugin\\Checker\\CanSavePayplugPaymentMethodChecker\:\:isEnabled\(\) expects Doctrine\\Common\\Collections\\Collection, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsCanSavePaymentMethodValidator.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\Gateway\\Validator\\Constraints\\IsOneyEnabledValidator\:\:validate\(\) has parameter \$value with no type specified\.$#'
+ identifier: missingType.parameter
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsOneyEnabledValidator.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\Gateway\\Validator\\Constraints\\IsPayPlugSecretKeyValidator\:\:validate\(\) has parameter \$value with no type specified\.$#'
+ identifier: missingType.parameter
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/IsPayPlugSecretKeyValidator.php
+
+ -
+ message: '#^Cannot access offset ''secretKey'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/PayplugPermissionValidator.php
+
+ -
+ message: '#^Cannot call method getConfig\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/PayplugPermissionValidator.php
+
+ -
+ message: '#^Cannot call method getData\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/PayplugPermissionValidator.php
+
+ -
+ message: '#^Cannot call method getGatewayConfig\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/PayplugPermissionValidator.php
+
+ -
+ message: '#^Parameter \#2 \$key of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientFactory\:\:create\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Gateway/Validator/Constraints/PayplugPermissionValidator.php
+
+ -
+ message: '#^Binary operation "\." between ''payment_'' and mixed results in an error\.$#'
+ identifier: binaryOp.invalid
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access offset ''customer_id'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$brand on mixed\.$#'
+ identifier: property.nonObject
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$code on mixed\.$#'
+ identifier: property.nonObject
+ count: 2
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$country on mixed\.$#'
+ identifier: property.nonObject
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$exp_month on mixed\.$#'
+ identifier: property.nonObject
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$exp_year on mixed\.$#'
+ identifier: property.nonObject
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$id on mixed\.$#'
+ identifier: property.nonObject
+ count: 4
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$last4 on mixed\.$#'
+ identifier: property.nonObject
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access property \$message on mixed\.$#'
+ identifier: property.nonObject
+ count: 2
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$brand of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setBrand\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$countryCode of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setCountryCode\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$expirationMonth of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setExpirationMonth\(\) expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$expirationYear of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setExpirationYear\(\) expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$externalId of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setExternalId\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$isLive of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setIsLive\(\) expects bool, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$last4 of method PayPlug\\SyliusPayPlugPlugin\\Entity\\Card\:\:setLast4\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$timestamp of method DateTimeImmutable\:\:setTimestamp\(\) expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Parameter \#2 \$array of function array_key_exists expects array, mixed given\.$#'
+ identifier: argument.type
+ count: 2
+ path: ../src/Handler/PaymentNotificationHandler.php
+
+ -
+ message: '#^Cannot access offset ''refund_from_sylius'' on mixed\.$#'
+ identifier: offsetAccess.nonOffsetAccessible
+ count: 1
+ path: ../src/Handler/RefundNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$externalId of method PayPlug\\SyliusPayPlugPlugin\\Entity\\RefundHistory\:\:setExternalId\(\) expects string\|null, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/RefundNotificationHandler.php
+
+ -
+ message: '#^Parameter \#1 \$value of method PayPlug\\SyliusPayPlugPlugin\\Entity\\RefundHistory\:\:setValue\(\) expects int, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/Handler/RefundNotificationHandler.php
+
+ -
+ message: '#^Call to static method Webmozart\\Assert\\Assert\:\:isInstanceOf\(\) with DateTimeInterface and ''DateTimeInterface'' will always evaluate to true\.$#'
+ identifier: staticMethod.alreadyNarrowedType
+ count: 1
+ path: ../src/MessageHandler/RefundPaymentGeneratedHandler.php
+
+ -
+ message: '#^Cannot call method add\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 1
+ path: ../src/MessageHandler/RefundPaymentGeneratedHandler.php
+
+ -
+ message: '#^Cannot call method apply\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/MessageHandler/RefundPaymentGeneratedHandler.php
+
+ -
+ message: '#^Cannot call method get\(\) on mixed\.$#'
+ identifier: method.nonObject
+ count: 2
+ path: ../src/MessageHandler/RefundPaymentGeneratedHandler.php
+
+ -
+ message: '#^Property PayPlug\\SyliusPayPlugPlugin\\MessageHandler\\RefundPaymentGeneratedHandler\:\:\$stateMachineFactory has no type specified\.$#'
+ identifier: missingType.property
+ count: 1
+ path: ../src/MessageHandler/RefundPaymentGeneratedHandler.php
+
+ -
+ message: '#^Parameter \#1 \$paymentId of method PayPlug\\SyliusPayPlugPlugin\\ApiClient\\PayPlugApiClientInterface\:\:abortPayment\(\) expects string, mixed given\.$#'
+ identifier: argument.type
+ count: 1
+ path: ../src/PaymentProcessing/AbortPaymentProcessor.php
+
+ -
+ message: '#^Binary operation "\-\=" between float\|int and mixed results in an error\.$#'
+ identifier: assignOp.invalid
+ count: 2
+ path: ../src/PaymentProcessing/RefundPaymentHandler.php
+
+ -
+ message: '#^Cannot cast mixed to float\.$#'
+ identifier: cast.double
+ count: 1
+ path: ../src/PaymentProcessing/RefundPaymentHandler.php
+
+ -
+ message: '#^Class Sylius\\RefundPlugin\\Command\\RefundUnits constructor invoked with 5 parameters, 4 required\.$#'
+ identifier: arguments.count
+ count: 1
+ path: ../src/PaymentProcessing/RefundPaymentHandler.php
+
+ -
+ message: '#^Method PayPlug\\SyliusPayPlugPlugin\\PaymentProcessing\\RefundPaymentHandler\:\:parseIdsToUnitRefunds\(\) should return array\ but returns list\