-
Notifications
You must be signed in to change notification settings - Fork 1
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
Handle Blik Level 0 payments #14
Changes from all commits
bbc8c24
be73810
c8d3d35
58ea867
61ef6c6
984bc9b
24cb7ab
e89fc41
c560aa2
ddf63ec
69bc7fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
$containerConfigurator->extension('sylius_ui', [ | ||
'events' => [ | ||
'sylius.shop.checkout.complete.summary' => [ | ||
'blocks' => [ | ||
'blik' => [ | ||
'template' => '@CommerceWeaversSyliusTpayPlugin/blik.html.twig', | ||
'priority' => 5, | ||
], | ||
], | ||
], | ||
], | ||
]); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4,6 +4,7 @@ | |||||
|
||||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||||||
|
||||||
use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateBlik0TransactionAction; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's adjust naming to @coldic3 suggestion
Suggested change
if @jakubtobiasz is fine with that |
||||||
use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateTransactionAction; | ||||||
use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\NotifyAction; | ||||||
use CommerceWeavers\SyliusTpayPlugin\Payum\Action\CaptureAction; | ||||||
|
@@ -20,6 +21,7 @@ | |||||
$services->set(CaptureAction::class) | ||||||
->args([ | ||||||
service('commerce_weavers.tpay.payum.factory.create_transaction'), | ||||||
service('commerce_weavers.tpay.payum.factory.create_blik0_transaction'), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or at least we can adjust service names
Suggested change
|
||||||
]) | ||||||
->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.capture']) | ||||||
; | ||||||
|
@@ -44,4 +46,14 @@ | |||||
|
||||||
$services->set(RefundAction::class) | ||||||
->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.refund']); | ||||||
|
||||||
$services->set(CreateBlik0TransactionAction::class) | ||||||
->args([ | ||||||
service('router'), | ||||||
param('commerce_weavers_tpay.payum.create_transaction.success_route'), | ||||||
param('commerce_weavers_tpay.payum.create_transaction.error_route'), | ||||||
param('commerce_weavers_tpay.payum.create_transaction.notify_route'), | ||||||
]) | ||||||
->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.create_blik0_transaction']) | ||||||
; | ||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\CreateBlik0TransactionFactory; | ||
use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\CreateTransactionFactory; | ||
use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\CreateTransactionFactoryInterface; | ||
use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\NotifyFactory; | ||
|
@@ -28,4 +29,8 @@ | |
$services->set('commerce_weavers.tpay.payum.factory.create_transaction', CreateTransactionFactory::class) | ||
->alias(CreateTransactionFactoryInterface::class, 'commerce_weavers.tpay.payum.factory.create_transaction') | ||
; | ||
|
||
$services->set('commerce_weavers.tpay.payum.factory.create_blik0_transaction', CreateBlik0TransactionFactory::class) | ||
->alias(CreateTransactionFactoryInterface::class, 'commerce_weavers.tpay.payum.factory.create_blik0_transaction') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Entity; | ||
|
||
use Sylius\Component\Core\Model\PaymentInterface; | ||
|
||
interface OrderLastNewPaymentAwareInterface | ||
{ | ||
public function getLastNewPayment(): ?PaymentInterface; | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,15 @@ | ||||||
<?php | ||||||
|
||||||
declare(strict_types=1); | ||||||
|
||||||
namespace CommerceWeavers\SyliusTpayPlugin\Entity; | ||||||
|
||||||
use Sylius\Component\Core\Model\PaymentInterface; | ||||||
|
||||||
trait OrderLastNewPaymentAwareTrait | ||||||
{ | ||||||
public function getLastNewPayment(): ?PaymentInterface | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Misleading naming. Payment on its own has
Suggested change
class name should be changed as well |
||||||
{ | ||||||
return $this->getLastPayment('cart'); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Form\DataTransformer; | ||
|
||
use Symfony\Component\Form\DataTransformerInterface; | ||
use Webmozart\Assert\Assert; | ||
|
||
class PaymentDetailsTransformer implements DataTransformerInterface | ||
{ | ||
public function transform(mixed $value): string | ||
{ | ||
Assert::isArray($value); | ||
if ($value === [] || !array_key_exists('blik', $value)) { | ||
return ''; | ||
} | ||
|
||
return $value['blik']; | ||
} | ||
|
||
public function reverseTransform($value): array | ||
{ | ||
return ['blik' => $value]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Form\Extension; | ||
|
||
use CommerceWeavers\SyliusTpayPlugin\Form\Type\PaymentDetailsType; | ||
use Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType; | ||
use Symfony\Component\Form\AbstractTypeExtension; | ||
use Symfony\Component\Form\FormBuilderInterface; | ||
|
||
final class CompleteTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function buildForm(FormBuilderInterface $builder, array $options): void | ||
{ | ||
$builder->add('others', PaymentDetailsType::class, [ | ||
'label' => 'commerce_weavers_sylius_tpay.payment.blik.token', | ||
// TODO some validation that works becuase this kind does not | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No todos nor comments should be committed to the codebase. You are more than welcome to open an issue and add it to board |
||
// 'constraints' => [ | ||
// new Length(['value' => 6, 'min' => 6, 'max' => 6, 'groups' => ['sylius']]), | ||
// ], | ||
'property_path' => 'last_new_payment.details[tpay]', | ||
'required' => false, | ||
]); | ||
} | ||
|
||
public static function getExtendedTypes(): iterable | ||
{ | ||
return [CompleteType::class]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Form\Type; | ||
|
||
use CommerceWeavers\SyliusTpayPlugin\Form\DataTransformer\PaymentDetailsTransformer; | ||
use Symfony\Component\Form\AbstractType; | ||
use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
use Symfony\Component\Form\FormBuilderInterface; | ||
|
||
class PaymentDetailsType extends AbstractType | ||
{ | ||
public function buildForm(FormBuilderInterface $builder, array $options): void | ||
{ | ||
$builder->addModelTransformer(new PaymentDetailsTransformer()); | ||
} | ||
|
||
public function getParent(): string | ||
{ | ||
return TextType::class; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api; | ||
|
||
use CommerceWeavers\SyliusTpayPlugin\Payum\Request\Api\CreateBlik0Transaction; | ||
use CommerceWeavers\SyliusTpayPlugin\Payum\Request\Api\CreateTransaction; | ||
use Payum\Core\Security\GenericTokenFactoryAwareInterface; | ||
use Payum\Core\Security\GenericTokenFactoryAwareTrait; | ||
use Payum\Core\Security\TokenInterface; | ||
use Sylius\Component\Core\Model\PaymentInterface; | ||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
use Symfony\Component\Routing\RouterInterface; | ||
use Tpay\OpenApi\Api\TpayApi; | ||
use Webmozart\Assert\Assert; | ||
|
||
/** | ||
* @property TpayApi $api | ||
*/ | ||
final class CreateBlik0TransactionAction extends BaseApiAwareAction implements GenericTokenFactoryAwareInterface | ||
{ | ||
use GenericTokenFactoryAwareTrait; | ||
|
||
public function __construct( | ||
private RouterInterface $router, | ||
private string $successRoute, | ||
private string $errorRoute, | ||
private string $notifyRoute, | ||
) { | ||
parent::__construct(); | ||
} | ||
|
||
/** | ||
* @param CreateTransaction $request | ||
*/ | ||
public function execute($request): void | ||
{ | ||
/** @var PaymentInterface $model */ | ||
$model = $request->getModel(); | ||
$details = $model->getDetails(); | ||
$token = $request->getToken(); | ||
Assert::notNull($token); | ||
|
||
$order = $model->getOrder(); | ||
Assert::notNull($order); | ||
$customer = $order->getCustomer(); | ||
Assert::notNull($customer); | ||
$localeCode = $order->getLocaleCode(); | ||
Assert::notNull($localeCode); | ||
$billingAddress = $order->getBillingAddress(); | ||
Assert::notNull($billingAddress); | ||
$notifyToken = $this->createNotifyToken($model, $token, $localeCode); | ||
$amount = $model->getAmount(); | ||
Assert::notNull($amount); | ||
|
||
$blikToken = $model->getDetails()['tpay']['blik']; | ||
|
||
$response = $this->api->transactions()->createTransaction([ | ||
'amount' => number_format($amount / 100, 2, thousands_separator: ''), | ||
'description' => sprintf('zamówienie #%s', $order->getNumber()), // TODO: Introduce translations | ||
'payer' => [ | ||
'email' => $customer->getEmail(), | ||
'name' => $billingAddress->getFullName(), | ||
], | ||
'pay' => [ | ||
'groupId' => 150, | ||
'blikPaymentData' => [ | ||
'blikToken' => $blikToken, | ||
], | ||
], | ||
'callbacks' => [ | ||
'payerUrls' => [ | ||
'success' => $this->router->generate($this->successRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), | ||
'error' => $this->router->generate($this->errorRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), | ||
], | ||
'notification' => [ | ||
'url' => $notifyToken->getTargetUrl(), | ||
], | ||
], | ||
]); | ||
|
||
$details['tpay']['transaction_id'] = $response['transactionId']; | ||
$details['tpay']['status'] = $response['status']; | ||
|
||
$model->setDetails($details); | ||
} | ||
|
||
public function supports($request): bool | ||
{ | ||
return $request instanceof CreateBlik0Transaction && $request->getModel() instanceof PaymentInterface; | ||
} | ||
|
||
private function createNotifyToken(PaymentInterface $payment, TokenInterface $token, string $localeCode): TokenInterface | ||
{ | ||
return $this->tokenFactory->createToken( | ||
$token->getGatewayName(), | ||
$payment, | ||
$this->router->generate($this->notifyRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,6 +18,7 @@ final class CaptureAction implements ActionInterface, GatewayAwareInterface | |||||
|
||||||
public function __construct( | ||||||
private CreateTransactionFactoryInterface $createTransactionFactory, | ||||||
private CreateTransactionFactoryInterface $createBlik0TransactionFactory, | ||||||
) { | ||||||
} | ||||||
|
||||||
|
@@ -29,6 +30,14 @@ public function execute($request): void | |||||
/** @var PaymentInterface $model */ | ||||||
$model = $request->getModel(); | ||||||
|
||||||
if ($this->transactionIsBlik($model)) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C'mon, it is widely accepted practice to put
Suggested change
|
||||||
$this->gateway->execute( | ||||||
$this->createBlik0TransactionFactory->createNewWithModel($request->getToken()), | ||||||
); | ||||||
|
||||||
return; | ||||||
} | ||||||
|
||||||
$this->gateway->execute( | ||||||
$this->createTransactionFactory->createNewWithModel($request->getToken()), | ||||||
); | ||||||
|
@@ -42,4 +51,11 @@ public function supports($request): bool | |||||
{ | ||||||
return $request instanceof Capture && $request->getModel() instanceof PaymentInterface; | ||||||
} | ||||||
|
||||||
private function transactionIsBlik(PaymentInterface $model): bool | ||||||
{ | ||||||
return array_key_exists('tpay', $model->getDetails()) && | ||||||
array_key_exists('blik', $model->getDetails()['tpay']) | ||||||
; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace CommerceWeavers\SyliusTpayPlugin\Payum\Factory; | ||
|
||
use CommerceWeavers\SyliusTpayPlugin\Payum\Request\Api\CreateBlik0Transaction; | ||
|
||
final class CreateBlik0TransactionFactory implements CreateTransactionFactoryInterface | ||
{ | ||
public function createNewWithModel(mixed $model): CreateBlik0Transaction | ||
{ | ||
return new CreateBlik0Transaction($model); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Templates like that should be rather placed in some subfolder. Shop prefix should be placed at least