Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One Click Blik #98

Merged
merged 24 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d0b85ab
Add API contract tests for 1-click BLIK
jakubtobiasz Oct 15, 2024
04a9309
Update contract tests for OneClick Blik
coldic3 Oct 16, 2024
4afa349
Save an alias for OneClick Blik in Level 0
coldic3 Oct 16, 2024
354880f
Extract transaction notification into a separate payum action
coldic3 Oct 17, 2024
68bc43b
Fix API authorization in test app
coldic3 Oct 17, 2024
257cac5
Rename PaymentNotificationAction into TpayNotificationAction
coldic3 Oct 17, 2024
351e8b6
Move checksum validation to NotifyTransactionAction
coldic3 Oct 17, 2024
0955251
Add NotifyAliasRegisterAction Payum action
coldic3 Oct 17, 2024
cf4474c
Add BlikAlias entity with Doctrine ORM mapping
coldic3 Oct 17, 2024
3253a56
Pay by Blik (OneClick Blik) using an alias
coldic3 Oct 17, 2024
cb18ff5
Add NotifyAliasUnregisterAction Payum action
coldic3 Oct 18, 2024
44e6b3b
Add test for an ambiguous Blik alias value
coldic3 Oct 18, 2024
92374db
Bring back PaymentNotificationAction for and introduce TpayNotificati…
coldic3 Oct 18, 2024
0386b14
Minor fixes and code cleanup
coldic3 Oct 24, 2024
e875f97
Fix persisting BlikAlias entity
coldic3 Oct 24, 2024
88b2039
List application names and codes if cannot pay using Blik alias becau…
coldic3 Oct 25, 2024
ad22b1b
Add support for a Blik alias with an application code
coldic3 Oct 25, 2024
92dc6ea
Replace save and use Blik alias parameters with BlikAliasAction enum
coldic3 Oct 27, 2024
b165e89
Add NotBlankIfBlikAliasActionIsRegister validation constraint
coldic3 Oct 28, 2024
8f6d2e3
Add OneOfPropertiesRequiredIfGatewayConfigTypeEquals validation const…
coldic3 Oct 28, 2024
ab10358
Add ForAuthorizedUserOnlyValidator validation constraint
coldic3 Oct 28, 2024
50cd0d2
Add ActiveBlikAliasPreconditionGuard
coldic3 Oct 28, 2024
113437f
Map Blik Alias exceptions to 400 HTTP response code
coldic3 Oct 29, 2024
a4c1248
Fix One Click Blik feature after conflicts
coldic3 Oct 29, 2024
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"symfony/http-foundation": "5.4.* || ^6.0",
"symfony/http-kernel": "5.4.* || ^6.0",
"symfony/routing": "5.4.* || ^6.0",
"symfony/uid": "5.4.*",
"tpay-com/tpay-openapi-php": "^1.8"
},
"conflict": {
Expand Down
6 changes: 6 additions & 0 deletions config/config/api_platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@

use CommerceWeavers\SyliusTpayPlugin\Api\Command\Exception\OrderCannotBeFoundException;
use CommerceWeavers\SyliusTpayPlugin\Api\Command\Exception\PaymentFailedException;
use CommerceWeavers\SyliusTpayPlugin\Api\Exception\BlikAliasAmbiguousValueException;
use CommerceWeavers\SyliusTpayPlugin\Api\Factory\Exception\UnresolvableNextCommandException;
use CommerceWeavers\SyliusTpayPlugin\Payment\Exception\PaymentCannotBeCancelledException;
use CommerceWeavers\SyliusTpayPlugin\PreconditionGuard\Exception\BlikAliasExpiredException;
use CommerceWeavers\SyliusTpayPlugin\PreconditionGuard\Exception\BlikAliasNotRegisteredException;

return function(ContainerConfigurator $configurator): void {
$configurator->extension('api_platform', [
Expand All @@ -16,6 +19,9 @@
PaymentCannotBeCancelledException::class => 400,
UnresolvableNextCommandException::class => 400,
PaymentFailedException::class => 424,
BlikAliasAmbiguousValueException::class => 400,
BlikAliasExpiredException::class => 400,
BlikAliasNotRegisteredException::class => 400,
],
'mapping' => [
'paths' => [
Expand Down
2 changes: 2 additions & 0 deletions config/config/payum.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
->encryption()
->defuseSecretKey('%env(PAYUM_CYPHER_KEY)%')
;

$payum->storages('%commerce_weavers_sylius_tpay.model.blik_alias.class%', ['doctrine' => 'orm']);
};
25 changes: 25 additions & 0 deletions config/doctrine/BlikAlias.orm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>

<doctrine-mapping
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"
>
<mapped-superclass name="CommerceWeavers\SyliusTpayPlugin\Entity\BlikAlias" table="cw_sylius_tpay_blik_alias">
<id name="id" column="id" type="integer">
<generator />
</id>

<field name="value" column="value" />
<field name="expirationDate" column="expiration_date" type="datetime" nullable="true" />
<field name="registered" column="registered" type="boolean">
<options>
<option name="default">false</option>
</options>
</field>

<one-to-one field="customer" target-entity="Sylius\Component\Core\Model\CustomerInterface">
<join-column name="customer_id" nullable="false" on-delete="CASCADE" />
</one-to-one>
</mapped-superclass>
</doctrine-mapping>
6 changes: 6 additions & 0 deletions config/routes_webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use CommerceWeavers\SyliusTpayPlugin\Controller\InitApplePayPaymentAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\PaymentNotificationAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\TpayNotificationAction;
use CommerceWeavers\SyliusTpayPlugin\Routing;
use Symfony\Component\HttpFoundation\Request;

Expand All @@ -15,6 +16,11 @@
->methods([Request::METHOD_POST])
;

$routes->add(Routing::WEBHOOK_NOTIFICATION, Routing::WEBHOOK_NOTIFICATION_PATH)
->controller(TpayNotificationAction::class)
->methods([Request::METHOD_POST])
;

$routes->add(Routing::WEBHOOK_PAYMENT_NOTIFICATION, Routing::WEBHOOK_PAYMENT_NOTIFICATION_PATH)
->controller(PaymentNotificationAction::class)
->methods([Request::METHOD_POST])
Expand Down
6 changes: 6 additions & 0 deletions config/serialization/Pay.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<attribute name="blikToken">
<group>commerce_weavers_sylius_tpay:shop:order:pay</group>
</attribute>
<attribute name="blikAliasAction">
<group>commerce_weavers_sylius_tpay:shop:order:pay</group>
</attribute>
<attribute name="blikAliasApplicationCode">
<group>commerce_weavers_sylius_tpay:shop:order:pay</group>
</attribute>
<attribute name="googlePayToken">
<group>commerce_weavers_sylius_tpay:shop:order:pay</group>
</attribute>
Expand Down
5 changes: 5 additions & 0 deletions config/services/api/command.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@

$services->set('commerce_weavers_sylius_tpay.api.command.pay_by_blik_handler', PayByBlikHandler::class)
->parent('commerce_weavers_sylius_tpay.api.command.abstract_pay_by_handler')
->args([
service('commerce_weavers_sylius_tpay.resolver.blik_alias'),
service('commerce_weavers_sylius_tpay.manager.blik_alias'),
service('commerce_weavers_sylius_tpay.precondition_guard.active_blik_alias'),
])
->tag('messenger.message_handler')
;

Expand Down
18 changes: 18 additions & 0 deletions config/services/api/serializer/normalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use CommerceWeavers\SyliusTpayPlugin\Api\Serializer\Normalizer\BlikAliasAmbiguousValueErrorNormalizer;

return function(ContainerConfigurator $container): void {
$services = $container->services();

$services->set('commerce_weavers_sylius_tpay.api.serializer.normalizer.blik_alias_ambiguous_value_error', BlikAliasAmbiguousValueErrorNormalizer::class)
->args([
service('api_platform.router'),
])
->tag('serializer.normalizer', ['priority' => -790])
;
};
16 changes: 15 additions & 1 deletion config/services/api/validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,27 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\NotBlankIfBlikAliasActionIsRegisterValidator;
use CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\NotBlankIfGatewayConfigTypeEqualsValidator;
use CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\OneOfPropertiesRequiredIfGatewayConfigTypeEqualsValidator;
use CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\TpayChannelIdEligibilityValidator;

return static function(ContainerConfigurator $container): void {
$services = $container->services();

$services->set('commerce_weavers_sylius_tpay.api.validator.constraint.not_blank_if_payment_method_type_equals', NotBlankIfGatewayConfigTypeEqualsValidator::class)
$services->set('commerce_weavers_sylius_tpay.api.validator.constraint.not_blank_if_blik_alias_action_is_register', NotBlankIfBlikAliasActionIsRegisterValidator::class)
->tag('validator.constraint_validator')
;

$services->set('commerce_weavers_sylius_tpay.api.validator.constraint.not_blank_if_gateway_config_type_equals', NotBlankIfGatewayConfigTypeEqualsValidator::class)
->args([
service('sylius.repository.order'),
service('payum.dynamic_gateways.cypher'),
])
->tag('validator.constraint_validator')
;

$services->set('commerce_weavers_sylius_tpay.api.validator.constraint.one_of_properties_required_if_gateway_config_type_equals', OneOfPropertiesRequiredIfGatewayConfigTypeEqualsValidator::class)
->args([
service('sylius.repository.order'),
service('payum.dynamic_gateways.cypher'),
Expand Down
12 changes: 11 additions & 1 deletion config/services/controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use CommerceWeavers\SyliusTpayPlugin\Controller\DisplayPaymentFailedPageAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\DisplayThankYouPageAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\DisplayWaitingForPaymentPage;
use CommerceWeavers\SyliusTpayPlugin\Controller\InitApplePayPaymentAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\PaymentNotificationAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\InitApplePayPaymentAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\TpayNotificationAction;
use CommerceWeavers\SyliusTpayPlugin\Controller\RetryPaymentAction;

return function(ContainerConfigurator $container): void {
Expand Down Expand Up @@ -67,4 +68,13 @@
])
->tag('controller.service_arguments')
;

$services->set(TpayNotificationAction::class)
->args([
service('commerce_weavers_sylius_tpay.tpay.security.notification.verifier.signature'),
service('commerce_weavers_sylius_tpay.repository.blik_alias'),
service('commerce_weavers_sylius_tpay.manager.blik_alias'),
])
->tag('controller.service_arguments')
;
};
1 change: 1 addition & 0 deletions config/services/payum/action.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
->args([
service('commerce_weavers_sylius_tpay.tpay.factory.create_blik_level_zero_payment_payload'),
service('commerce_weavers_sylius_tpay.payum.factory.token.notify'),
service('commerce_weavers_sylius_tpay.repository.blik_alias'),
])
->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.create_blik_level_zero_transaction'])
;
Expand Down
20 changes: 20 additions & 0 deletions config/services/precondition_guard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use CommerceWeavers\SyliusTpayPlugin\PreconditionGuard\ActiveBlikAliasPreconditionGuard;
use CommerceWeavers\SyliusTpayPlugin\PreconditionGuard\ActiveBlikAliasPreconditionGuardInterface;
use Sylius\Calendar\Provider\DateTimeProviderInterface;

return static function(ContainerConfigurator $container): void {
$services = $container->services();

$services->set('commerce_weavers_sylius_tpay.precondition_guard.active_blik_alias', ActiveBlikAliasPreconditionGuard::class)
->args([
service(DateTimeProviderInterface::class),
])
->alias(ActiveBlikAliasPreconditionGuardInterface::class, 'commerce_weavers_sylius_tpay.precondition_guard.active_blik_alias')
;
};
20 changes: 20 additions & 0 deletions config/services/resolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use CommerceWeavers\SyliusTpayPlugin\Resolver\BlikAliasResolver;
use CommerceWeavers\SyliusTpayPlugin\Resolver\BlikAliasResolverInterface;

return static function(ContainerConfigurator $container): void {
$services = $container->services();

$services->set('commerce_weavers_sylius_tpay.resolver.blik_alias', BlikAliasResolver::class)
->args([
service('commerce_weavers_sylius_tpay.repository.blik_alias'),
service('commerce_weavers_sylius_tpay.factory.blik_alias'),
])
->alias(BlikAliasResolverInterface::class, 'commerce_weavers_sylius_tpay.resolver.blik_alias')
;
};
1 change: 1 addition & 0 deletions config/services/tpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
$services->set('commerce_weavers_sylius_tpay.tpay.factory.create_blik_level_zero_payment_payload', CreateBlikLevelZeroPaymentPayloadFactory::class)
->args([
service('commerce_weavers_sylius_tpay.tpay.factory.create_redirect_based_payment_payload'),
service('sylius.context.channel'),
])
->alias(CreateBlikLevelZeroPaymentPayloadFactoryInterface::class, 'commerce_weavers_sylius_tpay.tpay.factory.create_blik_level_zero_payment_payload')
;
Expand Down
23 changes: 23 additions & 0 deletions config/services/validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use CommerceWeavers\SyliusTpayPlugin\Validator\Constraint\EncodedGooglePayTokenValidator;
use CommerceWeavers\SyliusTpayPlugin\Validator\Constraint\ForAuthorizedUserOnlyValidator;

return static function(ContainerConfigurator $container): void {
$services = $container->services();

$services->set('commerce_weavers_sylius_tpay.validator.constraint.encoded_google_pay_token', EncodedGooglePayTokenValidator::class)
->tag('validator.constraint_validator')
;

$services->set('commerce_weavers_sylius_tpay.validator.constraint.for_authorized_user_only', ForAuthorizedUserOnlyValidator::class)
->args([
service('security.helper'),
])
->tag('validator.constraint_validator')
;
};
30 changes: 24 additions & 6 deletions config/validation/Pay.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd">
<class name="CommerceWeavers\SyliusTpayPlugin\Api\Command\Pay">
<constraint name="CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\OneOfPropertiesRequiredIfGatewayConfigTypeEquals">
<option name="paymentMethodType">blik</option>
<option name="properties">
<value>blikToken</value>
<value>blikAliasAction</value>
</option>
<option name="allFieldsAreBlankErrorMessage">commerce_weavers_sylius_tpay.shop.pay.blik.required_fields</option>
<option name="groups">
<value>commerce_weavers_sylius_tpay:shop:order:pay</value>
</option>
</constraint>
<property name="applePayToken">
<constraint name="CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\NotBlankIfGatewayConfigTypeEquals">
<option name="paymentMethodType">apple_pay</option>
Expand All @@ -11,16 +22,23 @@
</constraint>
</property>
<property name="blikToken">
<constraint name="CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\NotBlankIfGatewayConfigTypeEquals">
<option name="paymentMethodType">blik</option>
<option name="fieldRequiredErrorMessage">commerce_weavers_sylius_tpay.shop.pay.blik_token.required</option>
<constraint name="Length">
<option name="value">6</option>
<option name="exactMessage">commerce_weavers_sylius_tpay.shop.pay.blik_token.length</option>
<option name="groups">
<value>commerce_weavers_sylius_tpay:shop:order:pay</value>
</option>
</constraint>
<constraint name="Length">
<option name="value">6</option>
<option name="exactMessage">commerce_weavers_sylius_tpay.shop.pay.blik_token.length</option>
<constraint name="CommerceWeavers\SyliusTpayPlugin\Api\Validator\Constraint\NotBlankIfBlikAliasActionIsRegister">
<option name="blikAliasActionPropertyName">blikAliasAction</option>
<option name="fieldRequiredErrorMessage">commerce_weavers_sylius_tpay.shop.pay.blik_token.required_with_alias_register</option>
<option name="groups">
<value>commerce_weavers_sylius_tpay:shop:order:pay</value>
</option>
</constraint>
</property>
<property name="blikAliasAction">
<constraint name="CommerceWeavers\SyliusTpayPlugin\Validator\Constraint\ForAuthorizedUserOnly">
<option name="groups">
<value>commerce_weavers_sylius_tpay:shop:order:pay</value>
</option>
Expand Down
Empty file removed migrations/.gitkeep
Empty file.
28 changes: 28 additions & 0 deletions migrations/Version20241024132714.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace CommerceWeaversSyliusTpayMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20241024132714 extends AbstractMigration
{
public function getDescription(): string
{
return 'Introduce BlikAlias entity.';
}

public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE cw_sylius_tpay_blik_alias (id INT AUTO_INCREMENT NOT NULL, customer_id INT NOT NULL, value VARCHAR(255) NOT NULL, expiration_date DATETIME DEFAULT NULL, registered TINYINT(1) DEFAULT false NOT NULL, UNIQUE INDEX UNIQ_72E078BE9395C3F3 (customer_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE cw_sylius_tpay_blik_alias ADD CONSTRAINT FK_72E078BE9395C3F3 FOREIGN KEY (customer_id) REFERENCES sylius_customer (id) ON DELETE CASCADE');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE cw_sylius_tpay_blik_alias DROP FOREIGN KEY FK_72E078BE9395C3F3');
$this->addSql('DROP TABLE cw_sylius_tpay_blik_alias');
}
}
3 changes: 3 additions & 0 deletions src/Api/Command/Pay.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace CommerceWeavers\SyliusTpayPlugin\Api\Command;

use CommerceWeavers\SyliusTpayPlugin\Api\Command\Contract\OrderTokenAwareInterface;
use CommerceWeavers\SyliusTpayPlugin\Api\Enum\BlikAliasAction;

final class Pay implements OrderTokenAwareInterface
{
Expand All @@ -14,6 +15,8 @@ public function __construct(
public readonly string $failureUrl,
public readonly ?string $applePayToken = null,
public readonly ?string $blikToken = null,
public readonly ?BlikAliasAction $blikAliasAction = null,
public readonly ?string $blikAliasApplicationCode = null,
public readonly ?string $googlePayToken = null,
public readonly ?string $encodedCardData = null,
public readonly ?string $tpayChannelId = null,
Expand Down
6 changes: 5 additions & 1 deletion src/Api/Command/PayByBlik.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

namespace CommerceWeavers\SyliusTpayPlugin\Api\Command;

use CommerceWeavers\SyliusTpayPlugin\Api\Enum\BlikAliasAction;

final class PayByBlik
{
public function __construct(
public readonly int $paymentId,
public readonly string $blikToken,
public readonly ?string $blikToken,
public readonly ?BlikAliasAction $blikAliasAction,
public readonly ?string $blikAliasApplicationCode,
) {
}
}
Loading
Loading