diff --git a/features/checkout/paying_for_order/changing_payment_method_after_order_confirmation.feature b/features/checkout/paying_for_order/changing_payment_method_after_order_confirmation.feature
index 4b5485859987..f49b46b5f0d8 100644
--- a/features/checkout/paying_for_order/changing_payment_method_after_order_confirmation.feature
+++ b/features/checkout/paying_for_order/changing_payment_method_after_order_confirmation.feature
@@ -34,11 +34,11 @@ Feature: Changing the method after order confirmation
Then I should see the thank you page
@api
- Scenario: Changing the payment method after placed order
+ Scenario: Changing the payment method for placed order
Given I added product "PHP T-Shirt" to the cart
When I complete addressing step with email "john@example.com" and "United States" based billing address
And I select "Free" shipping method
And I select "Cash on delivery" payment method
And I confirm my order
And I change payment method to "Offline"
- Then I should have chosen "offline" payment method for my order
+ Then I should have chosen "Offline" payment method for my order
diff --git a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
index eec693b8e259..d2513ac82b4b 100644
--- a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
+++ b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
@@ -830,11 +830,7 @@ public function iChangePaymentMethodTo(PaymentMethodInterface $paymentMethod): v
{
$this->client->request(
Request::METHOD_PATCH,
- \sprintf(
- '/new-api/shop/orders/%s/change-payments/%s',
- $this->sharedStorage->get('cart_token'),
- (string) $this->iriConverter->getItemFromIri($this->getCart()['payments'][0])->getId()
- ),
+ \sprintf('/new-api/shop/payments/%s/change-payments', $this->sharedStorage->get('cart_token')),
[],
[],
$this->getHeaders(),
diff --git a/src/Sylius/Bundle/ApiBundle/Command/ChangePaymentMethod.php b/src/Sylius/Bundle/ApiBundle/Command/ChangePaymentMethod.php
index 82e6f0b683e9..761c502a8603 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/ChangePaymentMethod.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/ChangePaymentMethod.php
@@ -14,11 +14,8 @@
namespace Sylius\Bundle\ApiBundle\Command;
/** @experimental */
-class ChangePaymentMethod implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface
+class ChangePaymentMethod
{
- /** @var string|null */
- public $orderTokenValue;
-
/**
* @psalm-immutable
*
@@ -38,28 +35,8 @@ public function __construct(string $paymentMethodCode)
$this->paymentMethodCode = $paymentMethodCode;
}
- public function getOrderTokenValue(): ?string
- {
- return $this->orderTokenValue;
- }
-
- public function setOrderTokenValue(?string $orderTokenValue): void
- {
- $this->orderTokenValue = $orderTokenValue;
- }
-
- public function getSubresourceId(): ?string
- {
- return $this->paymentId;
- }
-
- public function setSubresourceId(?string $subresourceId): void
- {
- $this->paymentId = $subresourceId;
- }
-
- public function getSubresourceIdAttributeKey(): string
+ public function setPaymentId(string $paymentId): void
{
- return 'paymentId';
+ $this->paymentId = $paymentId;
}
}
diff --git a/src/Sylius/Bundle/ApiBundle/CommandHandler/ChangePaymentMethodHandler.php b/src/Sylius/Bundle/ApiBundle/CommandHandler/ChangePaymentMethodHandler.php
index ebed8765f3c5..8c237c4d4f05 100644
--- a/src/Sylius/Bundle/ApiBundle/CommandHandler/ChangePaymentMethodHandler.php
+++ b/src/Sylius/Bundle/ApiBundle/CommandHandler/ChangePaymentMethodHandler.php
@@ -15,9 +15,7 @@
use SM\Factory\FactoryInterface;
use Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod;
-use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
-use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\Component\Core\Repository\PaymentRepositoryInterface;
@@ -27,49 +25,39 @@
/** @experimental */
final class ChangePaymentMethodHandler
{
- /** @var OrderRepositoryInterface */
- private $orderRepository;
-
/** @var PaymentMethodRepositoryInterface */
private $paymentMethodRepository;
/** @var PaymentRepositoryInterface */
private $paymentRepository;
- /** @var FactoryInterface */
- private $stateMachineFactory;
-
public function __construct(
- OrderRepositoryInterface $orderRepository,
PaymentMethodRepositoryInterface $paymentMethodRepository,
- PaymentRepositoryInterface $paymentRepository,
- FactoryInterface $stateMachineFactory
+ PaymentRepositoryInterface $paymentRepository
) {
- $this->orderRepository = $orderRepository;
$this->paymentMethodRepository = $paymentMethodRepository;
$this->paymentRepository = $paymentRepository;
- $this->stateMachineFactory = $stateMachineFactory;
}
- public function __invoke(ChangePaymentMethod $changePaymentMethod): OrderInterface
+ public function __invoke(ChangePaymentMethod $changePaymentMethod): PaymentInterface
{
- /** @var OrderInterface|null $order */
- $order = $this->orderRepository->findOneBy(['tokenValue' => $changePaymentMethod->orderTokenValue]);
-
- Assert::notNull($order, 'Order has not been found.');
-
/** @var PaymentMethodInterface|null $paymentMethod */
$paymentMethod = $this->paymentMethodRepository->findOneBy([
'code' => $changePaymentMethod->paymentMethodCode,
]);
Assert::notNull($paymentMethod, 'Payment method has not been found');
- $payment = $this->paymentRepository->findOneByOrderId($changePaymentMethod->paymentId, $order->getId());
+ /** @var PaymentInterface $payment */
+ $payment = $this->paymentRepository->find($changePaymentMethod->paymentId);
Assert::notNull($payment, 'Can not find payment with given identifier.');
- if ($payment->getState() === PaymentInterface::STATE_NEW) {
+
+ Assert::same(
+ $payment->getState(),
+ PaymentInterface::STATE_NEW,
+ 'Can not change payment method for this payment'
+ );
$payment->setMethod($paymentMethod);
- }
- return $order;
+ return $payment;
}
}
diff --git a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php
index f7fa14cb8244..1f919de3db1d 100644
--- a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php
+++ b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php
@@ -72,8 +72,8 @@ private function applyUserRulesToItem(
->leftJoin('customer.user', 'user')
->andWhere('user IS NULL')
->orWhere(sprintf('%s.customer IS NULL', $rootAlias))
-// ->andWhere(sprintf('%s.state = :state', $rootAlias))
-// ->setParameter('state', OrderInterface::STATE_CART)
+ ->andWhere(sprintf('%s.state = :state', $rootAlias))
+ ->setParameter('state', OrderInterface::STATE_CART)
;
return;
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
index d1ed44febdf9..75ac90c2fc9e 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
@@ -187,40 +187,6 @@
-
- PATCH
- /shop/orders/{id}/change-payments/{paymentId}
- input
- Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod
-
- order:change_payment_method
-
-
- order:read
-
-
- Selects payment methods for particular payment
-
-
- id
- path
- true
-
- string
-
-
-
- paymentId
- path
- true
-
- string
-
-
-
-
-
-
PATCH
/shop/orders/{id}/complete
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Payment.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Payment.xml
index f0aa1fa07797..3b96c9bcf388 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Payment.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Payment.xml
@@ -53,6 +53,19 @@
Completes Payment
+
+
+ PATCH
+ /shop/payments/{id}/change-payments
+ input
+ Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod
+
+ payment:change_payment_method
+
+
+ payment:read
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Commands/ChoosePaymentMethod.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Commands/ChoosePaymentMethod.xml
index eae1631a6473..da71c38041e0 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Commands/ChoosePaymentMethod.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Commands/ChoosePaymentMethod.xml
@@ -17,7 +17,7 @@
>
- order:change_payment_method
+ payment:change_payment_method
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
index 2128f45090c4..0fbbb0f4cf77 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
@@ -74,10 +74,8 @@
-
-
diff --git a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/ChangePaymentMethodHandlerSpec.php b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/ChangePaymentMethodHandlerSpec.php
new file mode 100644
index 000000000000..044e49213fd7
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/ChangePaymentMethodHandlerSpec.php
@@ -0,0 +1,100 @@
+beConstructedWith($paymentMethodRepository, $paymentRepository);
+ }
+
+ function it_changes_payment_method_to_specified_payment(
+ PaymentMethodRepositoryInterface $paymentMethodRepository,
+ PaymentMethodInterface $paymentMethod,
+ PaymentRepositoryInterface $paymentRepository,
+ PaymentInterface $payment
+ ): void {
+ $changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
+ $changePaymentMethod->setPaymentId('123');
+ $paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);
+
+ $paymentRepository->find('123')->willReturn($payment);
+
+ $payment->getState()->willReturn(PaymentInterface::STATE_NEW);
+ $payment->setMethod($paymentMethod)->shouldBeCalled();
+
+ $this($changePaymentMethod)->shouldReturn($payment);
+ }
+
+ function it_throws_an_exception_if_payment_method_with_given_code_has_not_been_found(
+ PaymentMethodRepositoryInterface $paymentMethodRepository
+ ): void {
+ $changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
+ $changePaymentMethod->setPaymentId('123');
+ $paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn(null);
+
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('__invoke', [$changePaymentMethod])
+ ;
+ }
+
+ function it_throws_an_exception_if_payment_has_not_be_found(
+ PaymentMethodRepositoryInterface $paymentMethodRepository,
+ PaymentMethodInterface $paymentMethod,
+ PaymentRepositoryInterface $paymentRepository
+ ): void {
+ $changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
+ $changePaymentMethod->setPaymentId('123');
+ $paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);
+
+ $paymentRepository->find('123')->willReturn(null);
+
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('__invoke', [$changePaymentMethod])
+ ;
+ }
+
+ function it_throws_an_exception_if_payment_is_in_different_state_than_new(
+ PaymentMethodRepositoryInterface $paymentMethodRepository,
+ PaymentMethodInterface $paymentMethod,
+ PaymentRepositoryInterface $paymentRepository,
+ PaymentInterface $payment
+ ): void
+ {
+ $changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
+ $changePaymentMethod->setPaymentId('123');
+ $paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);
+
+ $paymentRepository->find('123')->willReturn($payment);
+
+ $payment->getState()->willReturn(PaymentInterface::STATE_CANCELLED);
+
+ $this
+ ->shouldThrow(\InvalidArgumentException::class)
+ ->during('__invoke', [$changePaymentMethod])
+ ;
+ }
+}