Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .github/workflows/sylius.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,6 @@ jobs:
-
name: 'Install Sylius-Standard and Plugin'
run: 'make install -e SYLIUS_VERSION=${{ matrix.sylius }} SYMFONY_VERSION=${{ matrix.symfony }}'
-
name: 'Install certificates'
run: 'symfony server:ca:install'
-
name: 'Run Chrome headless'
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'
run: 'symfony server:start --port=8080 --daemon'
id: end-of-setup-sylius
-
name: 'Doctrine Schema Validate - Run'
Expand All @@ -98,14 +89,6 @@ jobs:
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'
# 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()
Expand Down
123 changes: 72 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
[![License](https://img.shields.io/packagist/l/payplug/payplug-sylius.svg)](https://github.com/payplug/SyliusPayPlugPlugin/blob/master/LICENSE)
![CI](https://github.com/payplug/SyliusPayPlugPlugin/workflows/CI/badge.svg?branch=master)
[![Version](https://img.shields.io/packagist/v/payplug/payplug-sylius.svg)](https://packagist.org/packages/payplug/payplug-sylius)
[![Total Downloads](https://poser.pugx.org/payplug/payplug-sylius/downloads)](https://packagist.org/packages/payplug/payplug-sylius)
[![License](https://img.shields.io/packagist/l/payplug/sylius-payplug-plugin.svg)](https://github.com/payplug/SyliusPayPlugPlugin/blob/master/LICENSE)
[![CI - Analysis](https://github.com/payplug/SyliusPayPlugPlugin/actions/workflows/analysis.yaml/badge.svg?branch=master)](https://github.com/payplug/SyliusPayPlugPlugin/actions/workflows/analysis.yaml)
[![CI - Sylius](https://github.com/payplug/SyliusPayPlugPlugin/actions/workflows/sylius.yaml/badge.svg?branch=master)](https://github.com/payplug/SyliusPayPlugPlugin/actions/workflows/sylius.yaml)
[![Version](https://img.shields.io/packagist/v/payplug/sylius-payplug-plugin.svg)](https://packagist.org/packages/payplug/sylius-payplug-plugin)
[![Total Downloads](https://poser.pugx.org/payplug/sylius-payplug-plugin/downloads)](https://packagist.org/packages/payplug/sylius-payplug-plugin)

<p align="center">
<a href="https://sylius.com" target="_blank">
<img src="https://demo.sylius.com/assets/shop/img/logo.png" />
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://media.sylius.com/sylius-logo-800-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://media.sylius.com/sylius-logo-800.png">
<img alt="Sylius Logo." src="https://media.sylius.com/sylius-logo-800.png">
</picture>
</a>
</p>

Expand All @@ -26,10 +31,10 @@ In local environment, the plugin will not work properly because you will not be

## Compatibility

| | Version |
| :--- |:----------------------|
| PHP | 7.4, 8.0, 8.1 |
| Sylius | 1.9, 1.10, 1.11, 1.12 |
| | Version |
| :--- |:--------|
| PHP | ^8.2 |
| Sylius | ^2.0 |

## Installation

Expand All @@ -46,14 +51,7 @@ In local environment, the plugin will not work properly because you will not be
bin/console doctrine:migrations:migrate
```

3. Copy templates that are overridden by Sylius into `templates/bundles/SyliusAdminBundle`

```shell
mkdir -p 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`
3. Add Payplug to refundable payment method for Sylius Refund Plugin in `config/services.yaml`

```yaml
parameters:
Expand All @@ -66,14 +64,7 @@ In local environment, the plugin will not work properly because you will not be
- payplug_american_express
```

5. Add Payplug routes in `config/routes.yaml`

```yaml
sylius_payplug:
resource: "@PayPlugSyliusPayPlugPlugin/config/routing.yaml"
```

8. Add Traits for Customer and PaymentMethod entities
4. Add Traits for Customer and PaymentMethod entities

* App\Entity\Customer\Customer

Expand Down Expand Up @@ -158,14 +149,14 @@ In local environment, the plugin will not work properly because you will not be
}
```

9. Process translations
5. Process translations

```bash
php bin/console translation:extract en PayPlugSyliusPayPlugPlugin --dump-messages
php bin/console translation:extract fr PayPlugSyliusPayPlugPlugin --dump-messages
```

10. Clear cache:
6. Clear cache:

```shell
php bin/console cache:clear
Expand All @@ -174,6 +165,60 @@ In local environment, the plugin will not work properly because you will not be
🎉 You are now ready to add Payplug Payment method.
In your back-office, go to `Configuration > Payment methods`, then click on `Create` and choose "**Payplug**".

### Assets installation (only for Sylius 2.0.x)

On sylius 2.0.x, there is no automatic load of assets.
You need to add the following lines in `assets/shop/controllers.json` to allow Sylius to use our assets:

```json
{
"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": []
}
```

> [!NOTE]
> On Sylius Standard >= 2.1, assets are automatically loaded when you install the plugin with flex.
> If you are upgrading from a 2.0.x version, read the [upgrade guide](https://github.com/Sylius/Sylius/blob/2.1/UPGRADE-2.1.md#assets)


## Logs

If you want to follow the logs in the production environment, you need to add the configuration in `config/packages/prod/monolog.yaml`, logs should be in `var/log/prod.log` which can be searched after the phrase `[Payum]` or `[Payplug]`:
Expand All @@ -199,30 +244,6 @@ Run the below command to see what Symfony services are shared with this plugin:
$ bin/console debug:container payplug_sylius_payplug_plugin
```

### Template overriding

This plugin override some sylius templates.
If you plan override them also, you should retrieve them in your application.

Copy Sylius templates overridden in plugin to your templates directory (e.g templates/bundles/)

```shell
mkdir -p templates/bundles/SyliusAdminBundle/
mkdir -p templates/bundles/SyliusShopBundle/
mkdir -p 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 :
```yaml
twig:
paths:
'%kernel.project_dir%/templates/bundles/SyliusAdminBundle': SyliusAdmin
'%kernel.project_dir%/templates/bundles/SyliusShopBundle': SyliusShop
'%kernel.project_dir%/templates/bundles/SyliusUiBundle': SyliusUi
```
## Development

See [How to contribute](CONTRIBUTING.md).
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"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",
"phpunit/phpunit": "^9.6",
"rector/rector": "2.0.4",
"sylius-labs/coding-standard": "4.4.0",
"sylius/test-application": "^2.1.0@alpha",
Expand Down
14 changes: 12 additions & 2 deletions src/Command/Handler/StatusPaymentRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClientInterface;
use PayPlug\SyliusPayPlugPlugin\Command\StatusPaymentRequest;
use PayPlug\SyliusPayPlugPlugin\Handler\PaymentNotificationHandler;
use Psr\Log\LoggerInterface;
use Sylius\Abstraction\StateMachine\StateMachineInterface;
use Sylius\Bundle\PaymentBundle\Provider\PaymentRequestProviderInterface;
use Sylius\Component\Payment\Model\PaymentInterface;
Expand All @@ -24,6 +25,7 @@ public function __construct(
private StateMachineInterface $stateMachine,
private PayPlugApiClientFactoryInterface $apiClientFactory,
private PaymentNotificationHandler $paymentNotificationHandler,
private LoggerInterface $logger,
) {}

public function __invoke(StatusPaymentRequest $statusPaymentRequest): void
Expand All @@ -43,8 +45,16 @@ public function __invoke(StatusPaymentRequest $statusPaymentRequest): void

// We don't have a forced status, so we retrieve the payment status from PayPlug
$client = $this->apiClientFactory->createForPaymentMethod($method);
// @phpstan-ignore-next-line - getDetails() return mixed
$payplugPayment = $client->retrieve($payment->getDetails()['payment_id'] ?? throw new \LogicException('No PayPlug payment ID found in payment details.'));
/** @var null|string $payplugPaymentId */
$payplugPaymentId = $payment->getDetails()['payment_id'] ?? null;
if (null === $payplugPaymentId) {
$this->logger->warning('No PayPlug payment ID found in payment details.', ['payment_id' => $payment->getId(), 'order_id' => $payment->getOrder()?->getId()]);
$payment->setDetails(['status' => PayPlugApiClientInterface::FAILED]);
$this->updatePaymentState($payment);
return;
}

$payplugPayment = $client->retrieve($payplugPaymentId);

$paymentRequest->setResponseData((array) $payplugPayment);
$details = new \ArrayObject($payment->getDetails());
Expand Down
3 changes: 2 additions & 1 deletion src/Creator/PayPlugPaymentDataCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public function create(
/** @var CustomerInterface $customer */
$customer = $order->getCustomer();

$details = new ArrayObject($payment->getDetails());
/** @var ArrayObject<array-key, mixed> $details */
$details = new ArrayObject();
$details['amount'] = $payment->getAmount();
$details['currency'] = $payment->getCurrencyCode();

Expand Down
8 changes: 7 additions & 1 deletion src/PaymentProcessing/AbortPaymentProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ public function onFailedCompleteTransitionEvent(CompletedEvent $event): void

public function process(PaymentInterface $payment): void
{
$paymentId = $payment->getDetails()['payment_id'] ?? null;
if (null === $paymentId) {
// Payment not even started on payplug
return;
}

try {
// When a payment is failed on Sylius, also abort it on PayPlug.
// This should prevent the case that if we are already on PayPlug payment page
// and go to the order history in another tab to click on pay again, then fail the transaction
// and go back on the first PayPlug payment page and succeed it, it stays failed as its first payment model is already failed
$this->payPlugApiClient->abortPayment($payment->getDetails()['payment_id']);
$this->payPlugApiClient->abortPayment($paymentId);
} catch (HttpException) {
}
}
Expand Down
Loading