Skip to content

Commit

Permalink
MOL-245: Add PayPal Express
Browse files Browse the repository at this point in the history
  • Loading branch information
boxblinkracer committed Dec 1, 2023
1 parent 9dc38d8 commit 6fc14cd
Show file tree
Hide file tree
Showing 78 changed files with 2,936 additions and 306 deletions.
55 changes: 31 additions & 24 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ NODE_VERSION:=$(shell node -v)


help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@printf "\033[33mInstallation:%-30s\033[0m %s\n"
@grep -E '^[a-zA-Z_-]+:.*?##1 .*$$' $(firstword $(MAKEFILE_LIST)) | awk 'BEGIN {FS = ":.*?##1 "}; {printf "\033[33m - %-30s\033[0m %s\n", $$1, $$2}'
@echo "---------------------------------------------------------------------------------------------------------"
@printf "\033[36mDevelopment:%-30s\033[0m %s\n"
@grep -E '^[a-zA-Z_-]+:.*?##2 .*$$' $(firstword $(MAKEFILE_LIST)) | awk 'BEGIN {FS = ":.*?##2 "}; {printf "\033[36m - %-30s\033[0m %s\n", $$1, $$2}'
@echo "---------------------------------------------------------------------------------------------------------"
@printf "\033[35mDevOps:%-30s\033[0m %s\n"
@grep -E '^[a-zA-Z_-]+:.*?##3 .*$$' $(firstword $(MAKEFILE_LIST)) | awk 'BEGIN {FS = ":.*?##3 "}; {printf "\033[35m - %-30s\033[0m %s\n", $$1, $$2}'

# ------------------------------------------------------------------------------------------------------------

prod: ## Installs all production dependencies
prod: ##1 Installs all production dependencies
# do not switch to production composer PROD, otherwise it would
# also install shopware in here -> we just need it for the release composer.json file
# so just switch to our dev dependency variant
Expand All @@ -27,18 +34,18 @@ prod: ## Installs all production dependencies
cd src/Resources/app/administration && npm install --omit=dev
cd src/Resources/app/storefront && npm install --production

dev: ## Installs all dev dependencies
dev: ##1 Installs all dev dependencies
php switch-composer.php dev
@composer validate
@composer install
cd src/Resources/app/administration && npm install
cd src/Resources/app/storefront && npm install
curl -1sLf 'https://dl.cloudsmith.io/public/friendsofshopware/stable/setup.deb.sh' | sudo -E bash && sudo apt install shopware-cli

install: ## [deprecated] Installs all production dependencies. Please use "make prod" now.
install: ##1 [deprecated] Installs all production dependencies. Please use "make prod" now.
@make prod -B

clean: ## Cleans all dependencies and files
clean: ##1 Cleans all dependencies and files
rm -rf vendor/*
# ------------------------------------------------------
rm -rf .reports | true
Expand All @@ -51,7 +58,7 @@ clean: ## Cleans all dependencies and files
rm -rf ./src/Resources/public/administration
rm -rf ./src/Resources/public/molllie-payments.js

build: ## Installs the plugin, and builds the artifacts using the Shopware build commands.
build: ##3 Installs the plugin, and builds the artifacts using the Shopware build commands.
php switch-composer.php prod
cd ../../.. && export NODE_OPTIONS=--openssl-legacy-provider && shopware-cli extension build custom/plugins/MolliePayments
php switch-composer.php dev
Expand All @@ -65,67 +72,67 @@ build: ## Installs the plugin, and builds the artifacts using the Shopware build
cd ../../.. && php bin/console --no-debug assets:install
cd ../../.. && php bin/console --no-debug cache:clear

fixtures: ## Installs all available testing fixtures of the Mollie plugin
fixtures: ##3 Installs all available testing fixtures of the Mollie plugin
cd ../../.. && php bin/console --no-debug cache:clear
cd ../../.. && php bin/console --no-debug fixture:load:group mollie

# ------------------------------------------------------------------------------------------------------------

phpcheck: ## Starts the PHP syntax checks
phpcheck: ##2 Starts the PHP syntax checks
@find . -name '*.php' -not -path "./vendor/*" -not -path "./tests/*" | xargs -n 1 -P4 php -l

phpmin: ## Starts the PHP compatibility checks
phpmin: ##2 Starts the PHP compatibility checks
@php vendor/bin/phpcs -p --standard=PHPCompatibility --extensions=php --runtime-set testVersion 7.2 ./src

csfix: ## Starts the PHP CS Fixer
csfix: ##2 Starts the PHP CS Fixer
@PHP_CS_FIXER_IGNORE_ENV=1 php vendor/bin/php-cs-fixer fix --config=./.php_cs.php --dry-run

stan: ## Starts the PHPStan Analyser
stan: ##2 Starts the PHPStan Analyser
@php vendor/bin/phpstan analyse -c ./.phpstan.neon

phpunit: ## Starts all PHPUnit Tests
phpunit: ##2 Starts all PHPUnit Tests
@XDEBUG_MODE=coverage php vendor/bin/phpunit --configuration=phpunit.xml --coverage-html ./.reports/phpunit/coverage

infection: ## Starts all Infection/Mutation tests
infection: ##2 Starts all Infection/Mutation tests
@XDEBUG_MODE=coverage php vendor/bin/infection --configuration=./.infection.json --log-verbosity=all --debug

insights: ## Starts the PHPInsights Analyser
insights: ##2 Starts the PHPInsights Analyser
@php vendor/bin/phpinsights analyse --no-interaction

jest: ## Starts all Jest tests
jest: ##2 Starts all Jest tests
cd ./src/Resources/app/administration && ./node_modules/.bin/jest --config=.jest.config.js --coverage
cd ./src/Resources/app/storefront && ./node_modules/.bin/jest --config=.jest.config.js --coverage

stryker: ## Starts the Stryker Jest Mutation Tests
stryker: ##2 Starts the Stryker Jest Mutation Tests
cd ./src/Resources/app/administration && ./node_modules/.bin/stryker run .stryker.conf.json
@# Storefront has no tests at the moment
@# cd ./src/Resources/app/storefront && ./node_modules/.bin/stryker run .stryker.conf.json

eslint: ## Starts the ESLinter
eslint: ##2 Starts the ESLinter
cd ./src/Resources/app/administration && ./node_modules/.bin/eslint --config ./.eslintrc.json ./src
cd ./src/Resources/app/storefront && ./node_modules/.bin/eslint --config ./.eslintrc.json ./src

stylelint: ## Starts the Stylelinter
stylelint: ##2 Starts the Stylelinter
cd ./src/Resources/app/administration && ./node_modules/.bin/stylelint --allow-empty-input ./src/**/*.scss
cd ./src/Resources/app/storefront && ./node_modules/.bin/stylelint --allow-empty-input ./src/**/*.scss

configcheck: ## Tests and verifies the plugin configuration file
configcheck: ##2 Tests and verifies the plugin configuration file
cd ./tests/Custom && php verify-plugin-config.php

# ------------------------------------------------------------------------------------------------------------

snippetcheck: ## Tests and verifies all plugin snippets
snippetcheck: ##2 Tests and verifies all plugin snippets
php vendor/bin/phpunuhi validate --configuration=./.phpunuhi.xml --report-format=junit --report-output=./.phpunuhi/junit.xml

snippetexport: ## Exports all snippets
snippetexport: ##2 Exports all snippets
php vendor/bin/phpunuhi export --configuration=./.phpunuhi.xml --dir=./.phpunuhi

snippetimport: ## Imports the provided snippet set [set=xyz file=xz.csv]
snippetimport: ##2 Imports the provided snippet set [set=xyz file=xz.csv]
php vendor/bin/phpunuhi import --configuration=./.phpunuhi.xml --set=$(set) --file=$(file) --intent=1

# ------------------------------------------------------------------------------------------------------------

pr: ## Prepares everything for a Pull Request
pr: ##2 Prepares everything for a Pull Request
@PHP_CS_FIXER_IGNORE_ENV=1 php vendor/bin/php-cs-fixer fix --config=./.php_cs.php
@make phpcheck -B
@make phpmin -B
Expand All @@ -141,7 +148,7 @@ pr: ## Prepares everything for a Pull Request

# -------------------------------------------------------------------------------------------------

release: ## Builds a PROD version and creates a ZIP file in plugins/.build.
release: ##3 Builds a PROD version and creates a ZIP file in plugins/.build.
ifneq (,$(findstring v12,$(NODE_VERSION)))
$(warning Attention, reqruires Node v14 or higher to build a release!)
@exit 1
Expand Down
4 changes: 2 additions & 2 deletions src/Components/ApplePayDirect/ApplePayDirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ public function prepareCustomer(string $firstname, string $lastname, string $ema
# if we are not logged in,
# then we have to create a new guest customer for our express order
if (!$this->customerService->isCustomerLoggedIn($context)) {
$customer = $this->customerService->createApplePayDirectCustomer(
$customer = $this->customerService->createGuestAccount(
$firstname,
$lastname,
$email,
Expand All @@ -371,7 +371,7 @@ public function prepareCustomer(string $firstname, string $lastname, string $ema
# now start the login of our customer.
# Our SalesChannelContext will be correctly updated after our
# forward to the finish-payment page.
$this->customerService->customerLogin($customer, $context);
$this->customerService->loginCustomer($customer, $context);
}

# also (always) update our payment method to use Apple Pay for our cart
Expand Down
189 changes: 189 additions & 0 deletions src/Components/PaypalExpress/PayPalExpress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

namespace Kiener\MolliePayments\Components\PaypalExpress;

use Kiener\MolliePayments\Factory\MollieApiFactory;
use Kiener\MolliePayments\Repository\PaymentMethod\PaymentMethodRepository;
use Kiener\MolliePayments\Service\CartServiceInterface;
use Kiener\MolliePayments\Service\CustomerService;
use Kiener\MolliePayments\Service\MollieApi\Builder\MollieOrderPriceBuilder;
use Kiener\MolliePayments\Service\Router\RoutingBuilder;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;

class PayPalExpress
{

/**
* @var PaymentMethodRepository
*/
private $repoPaymentMethods;

/**
* @var MollieApiFactory
*/
private $mollieApiFactory;

/**
* @var MollieOrderPriceBuilder
*/
private $priceBuilder;

/**
* @var RoutingBuilder
*/
private $urlBuilder;

/**
* @var CustomerService
*/
private $customerService;

/**
* @var CartServiceInterface
*/
private $cartService;

/**
* @param PaymentMethodRepository $repoPaymentMethods
* @param MollieApiFactory $mollieApiFactory
* @param MollieOrderPriceBuilder $priceBuilder
* @param RoutingBuilder $urlBuilder
* @param CustomerService $customerService
* @param CartServiceInterface $cartService
*/
public function __construct(PaymentMethodRepository $repoPaymentMethods, MollieApiFactory $mollieApiFactory, MollieOrderPriceBuilder $priceBuilder, RoutingBuilder $urlBuilder, CustomerService $customerService, CartServiceInterface $cartService)
{
$this->repoPaymentMethods = $repoPaymentMethods;
$this->mollieApiFactory = $mollieApiFactory;
$this->priceBuilder = $priceBuilder;
$this->urlBuilder = $urlBuilder;
$this->customerService = $customerService;
$this->cartService = $cartService;
}


/**
* @param SalesChannelContext $context
* @return bool
*/
public function isPaypalExpressEnabled(SalesChannelContext $context): bool
{
try {
$methodID = $this->getActivePaypalExpressID($context);

return (!empty($methodID));
} catch (\Exception $ex) {
return false;
}
}

/**
* @param SalesChannelContext $context
* @return string
* @throws \Exception
*/
public function getActivePaypalExpressID(SalesChannelContext $context): string
{
return $this->repoPaymentMethods->getActivePaypalExpressID($context->getContext());
}

public function getActivePaypalID(SalesChannelContext $context)
{
return $this->repoPaymentMethods->getActivePaypalID($context->getContext());

}


/**
* @param Cart $cart
* @param SalesChannelContext $context
* @return string
* @throws \Mollie\Api\Exceptions\ApiException
*/
public function startSession(Cart $cart, SalesChannelContext $context): string
{
$mollie = $this->mollieApiFactory->getClient($context->getSalesChannelId());

$params = [
'method' => 'paypal',
'methodDetails' => [
'checkoutFlow' => 'express',
],
'amount' => $this->priceBuilder->build(
$cart->getPrice()->getTotalPrice(),
$context->getCurrency()->getIsoCode()
),
'description' => 'test',
# 'redirectUrl' => $this->urlBuilder->buildPaypalExpressRedirectUrl(),
# 'cancelUrl' => $this->urlBuilder->buildPaypalExpressCancelUrl(),
];

$session = $mollie->sessions->create($params);

$redirectUrl = $session->getRedirectUrl();

if (empty($redirectUrl)) {
return '';
# throw new \Exception('Paypal Express RedirectURL is empty! Cannot proceed');
}

return $redirectUrl;
}


/**
* @param string $firstname
* @param string $lastname
* @param string $email
* @param string $street
* @param string $zipcode
* @param string $city
* @param string $countryCode
* @param string $paymentToken
* @param SalesChannelContext $context
* @return SalesChannelContext
* @throws \Exception
*/
public function prepareCustomer(string $firstname, string $lastname, string $email, string $street, string $zipcode, string $city, string $countryCode, string $paymentToken, SalesChannelContext $context): SalesChannelContext
{
if (empty($paymentToken)) {
throw new \Exception('PaymentToken not found!');
}


$paypalExpressId = $this->getActivePaypalExpressID($context);

# if we are not logged in,
# then we have to create a new guest customer for our express order
if (!$this->customerService->isCustomerLoggedIn($context)) {
$customer = $this->customerService->createGuestAccount(
$firstname,
$lastname,
$email,
'',
$street,
$zipcode,
$city,
$countryCode,
$paypalExpressId,
$context
);

if (!$customer instanceof CustomerEntity) {
throw new \Exception('Error when creating customer!');
}

# now start the login of our customer.
# Our SalesChannelContext will be correctly updated after our
# forward to the finish-payment page.
$this->customerService->loginCustomer($customer, $context);
}

# also (always) update our payment method to use Apple Pay for our cart
return $this->cartService->updatePaymentMethod($context, $paypalExpressId);
}


}
Loading

0 comments on commit 6fc14cd

Please sign in to comment.