diff --git a/src/Facade/MolliePaymentDoPay.php b/src/Facade/MolliePaymentDoPay.php index 71c3fdff8..d1ae2bb3e 100644 --- a/src/Facade/MolliePaymentDoPay.php +++ b/src/Facade/MolliePaymentDoPay.php @@ -26,6 +26,7 @@ use Mollie\Api\Exceptions\ApiException; use Mollie\Api\Resources\OrderLine; use Psr\Log\LoggerInterface; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct; use Shopware\Core\System\SalesChannel\SalesChannelContext; @@ -230,10 +231,14 @@ public function startMolliePayment(string $paymentMethod, AsyncPaymentTransactio $orderCustomFields->setSubscriptionData($subscriptionId, ''); } + /** + * @var OrderLineItemCollection $orderLineItems + */ + $orderLineItems = $order->getLineItems(); # we save that data in both, the order and # the order line items $this->updaterOrderCustomFields->updateOrder($order->getId(), $orderCustomFields, $salesChannelContext->getContext()); - $this->updaterLineItemCustomFields->updateOrderLineItems($molliePaymentData->getMollieLineItems(), $salesChannelContext); + $this->updaterLineItemCustomFields->updateOrderLineItems($molliePaymentData->getMollieLineItems(), $orderLineItems, $salesChannelContext); # this condition somehow looks weird to me (TODO) diff --git a/src/Resources/config/services/api.xml b/src/Resources/config/services/api.xml index 0b2b0d072..24a8f2e4e 100644 --- a/src/Resources/config/services/api.xml +++ b/src/Resources/config/services/api.xml @@ -26,6 +26,7 @@ + diff --git a/src/Service/MollieApi/Order.php b/src/Service/MollieApi/Order.php index 3e1a7e145..7bf097f9f 100644 --- a/src/Service/MollieApi/Order.php +++ b/src/Service/MollieApi/Order.php @@ -9,12 +9,14 @@ use Kiener\MolliePayments\Factory\MollieApiFactory; use Kiener\MolliePayments\Handler\Method\CreditCardPayment; use Kiener\MolliePayments\Handler\PaymentHandler; +use Kiener\MolliePayments\Service\CustomerService; use Kiener\MolliePayments\Service\MollieApi\Payment as MolliePayment; use Kiener\MolliePayments\Service\MollieApi\Payment as PaymentApiService; use Kiener\MolliePayments\Service\MollieApi\RequestAnonymizer\MollieRequestAnonymizer; use Kiener\MolliePayments\Service\Router\RoutingBuilder; use Kiener\MolliePayments\Service\SettingsService; use Kiener\MolliePayments\Struct\MollieApi\ShipmentTrackingInfoStruct; +use Kiener\MolliePayments\Struct\OrderLineItemEntity\OrderLineItemEntityAttributes; use Mollie\Api\Exceptions\ApiException; use Mollie\Api\Resources\Order as MollieOrder; use Mollie\Api\Resources\OrderLine; @@ -27,6 +29,7 @@ use RuntimeException; use Shopware\Core\Checkout\Customer\CustomerEntity; use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Checkout\Shipping\ShippingMethodEntity; use Shopware\Core\System\SalesChannel\SalesChannelContext; @@ -63,6 +66,11 @@ class Order */ private $settingsService; + /** + * @var CustomerService + */ + private $customerService; + /** * @param MollieApiFactory $clientFactory * @param MolliePayment $paymentApiService @@ -71,7 +79,7 @@ class Order * @param LoggerInterface $logger * @param SettingsService $settingsService */ - public function __construct(MollieApiFactory $clientFactory, PaymentApiService $paymentApiService, RoutingBuilder $routingBuilder, MollieRequestAnonymizer $requestAnonymizer, LoggerInterface $logger, SettingsService $settingsService) + public function __construct(MollieApiFactory $clientFactory, PaymentApiService $paymentApiService, RoutingBuilder $routingBuilder, MollieRequestAnonymizer $requestAnonymizer, LoggerInterface $logger, SettingsService $settingsService, CustomerService $customerService) { $this->clientFactory = $clientFactory; $this->logger = $logger; @@ -79,6 +87,7 @@ public function __construct(MollieApiFactory $clientFactory, PaymentApiService $ $this->routingBuilder = $routingBuilder; $this->requestAnonymizer = $requestAnonymizer; $this->settingsService = $settingsService; + $this->customerService = $customerService; } /** @@ -360,6 +369,22 @@ private function createNewOrderPayment(MollieOrder $mollieOrder, string $payment $paymentHandler->setEnableSingleClickPayment(true); } + $lineItems = $order->getLineItems(); + + if ($settings->isSubscriptionsEnabled() && $lineItems instanceof OrderLineItemCollection) { + # mollie customer ID is required for recurring payments, see https://docs.mollie.com/reference/v2/orders-api/create-order-payment + $mollieCustomerId = $this->customerService->getMollieCustomerId($customer->getId(), $salesChannelContext->getSalesChannelId(), $salesChannelContext->getContext()); + + foreach ($lineItems as $lineItem) { + $attributes = new OrderLineItemEntityAttributes($lineItem); + if ($attributes->isSubscriptionProduct()) { + $newPaymentData['payment']['sequenceType'] = 'first'; + $newPaymentData['payment']['customerId'] = $mollieCustomerId; + break; + } + } + } + # now we have to add payment specific data # like we would do with initial orders too $tmpOrder = $paymentHandler->processPaymentMethodSpecificParameters($newPaymentData, $order, $salesChannelContext, $customer); diff --git a/src/Service/Order/UpdateOrderLineItems.php b/src/Service/Order/UpdateOrderLineItems.php index 9fc158495..c014762c9 100644 --- a/src/Service/Order/UpdateOrderLineItems.php +++ b/src/Service/Order/UpdateOrderLineItems.php @@ -6,6 +6,8 @@ use Mollie\Api\Resources\Order; use Mollie\Api\Resources\OrderLine; use Mollie\Api\Types\OrderLineType; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity; use Shopware\Core\System\SalesChannel\SalesChannelContext; class UpdateOrderLineItems @@ -29,7 +31,7 @@ public function __construct(OrderLineItemRepositoryInterface $orderLineRepositor * @param SalesChannelContext $salesChannelContext * @return void */ - public function updateOrderLineItems(array $orderLines, SalesChannelContext $salesChannelContext): void + public function updateOrderLineItems(array $orderLines, OrderLineItemCollection $shopwareOrderLines, SalesChannelContext $salesChannelContext): void { foreach ($orderLines as $orderLine) { if ($orderLine->type === OrderLineType::TYPE_SHIPPING_FEE) { @@ -41,13 +43,20 @@ public function updateOrderLineItems(array $orderLines, SalesChannelContext $sal if (empty($shopwareLineItemId)) { continue; } + /** @var OrderLineItemEntity $shopwareLine */ + $shopwareLine = $shopwareOrderLines->get($shopwareLineItemId); + if (!$shopwareLine instanceof OrderLineItemEntity) { + continue; + } + + ## we need some customfields for later when we edit an order, for example subscription information + $originalCustomFields = $shopwareLine->getPayload()['customFields'] ?? []; + $originalCustomFields['order_line_id'] = $orderLine->id; $data = [ - 'id' => $shopwareLineItemId, + 'id' => $shopwareLine->getId(), 'customFields' => [ - 'mollie_payments' => [ - 'order_line_id' => $orderLine->id - ] + 'mollie_payments' => $originalCustomFields ] ]; diff --git a/tests/PHPUnit/Service/MollieApi/OrderTest.php b/tests/PHPUnit/Service/MollieApi/OrderTest.php index 1d7e4d0f0..1026177ff 100644 --- a/tests/PHPUnit/Service/MollieApi/OrderTest.php +++ b/tests/PHPUnit/Service/MollieApi/OrderTest.php @@ -4,6 +4,7 @@ use Kiener\MolliePayments\Exception\CouldNotFetchMollieOrderException; use Kiener\MolliePayments\Factory\MollieApiFactory; +use Kiener\MolliePayments\Service\CustomerService; use Kiener\MolliePayments\Service\MollieApi\Order as MollieOrderApi; use Kiener\MolliePayments\Service\MollieApi\Payment as MolliePaymentApi; use Kiener\MolliePayments\Service\MollieApi\RequestAnonymizer\MollieRequestAnonymizer; @@ -75,7 +76,8 @@ protected function setUp(): void $this->buildRoutingBuilder($this, ''), new MollieRequestAnonymizer('*'), new NullLogger(), - $this->createMock(SettingsService::class) + $this->createMock(SettingsService::class), + $this->createMock(CustomerService::class), ); }