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

PIPRES-261: Set carrier for recurring order #818

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
9 changes: 9 additions & 0 deletions controllers/front/subscriptionWebhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Mollie\Controller\AbstractMollieController;
use Mollie\Errors\Http\HttpStatusCode;
use Mollie\Handler\ErrorHandler\ErrorHandler;
use Mollie\Logger\PrestaLoggerInterface;
use Mollie\Subscription\Handler\RecurringOrderHandler;

if (!defined('_PS_VERSION_')) {
Expand Down Expand Up @@ -62,9 +63,17 @@ protected function executeWebhook()
/** @var ErrorHandler $errorHandler */
$errorHandler = $this->module->getService(ErrorHandler::class);

/** @var PrestaLoggerInterface $logger */
$logger = $this->module->getService(PrestaLoggerInterface::class);

try {
$recurringOrderHandler->handle($transactionId);
} catch (\Throwable $exception) {
$logger->error('Failed to handle recurring order', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$errorHandler->handle($exception, null, false);

$this->respond('failed', HttpStatusCode::HTTP_BAD_REQUEST);
Expand Down
16 changes: 6 additions & 10 deletions subscription/Exception/CouldNotHandleRecurringOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,21 @@

namespace Mollie\Subscription\Exception;

use Throwable;

class CouldNotHandleRecurringOrder extends MollieSubscriptionException
{
public static function failedToCreateOrderPaymentFee(Throwable $exception): CouldNotHandleRecurringOrder
public static function failedToFindSelectedCarrier(): CouldNotHandleRecurringOrder
{
return new self(
'Failed to create order payment fee',
ExceptionCode::ORDER_FAILED_TO_CREATE_ORDER_PAYMENT_FEE,
$exception
'Failed to find selected carrier',
ExceptionCode::RECURRING_ORDER_FAILED_TO_FIND_SELECTED_CARRIER
);
}

public static function failedToUpdateOrderTotalWithPaymentFee(Throwable $exception): CouldNotHandleRecurringOrder
public static function failedToApplySelectedCarrier(): CouldNotHandleRecurringOrder
{
return new self(
'Failed to update order total with payment fee.',
ExceptionCode::ORDER_FAILED_TO_UPDATE_ORDER_TOTAL_WITH_PAYMENT_FEE,
$exception
'Failed to apply selected carrier',
ExceptionCode::RECURRING_ORDER_FAILED_TO_APPLY_SELECTED_CARRIER
);
}
}
21 changes: 12 additions & 9 deletions subscription/Exception/ExceptionCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ class ExceptionCode
{
//Order error codes starts from 1000

public const ORDER_FAILED_TO_CREATE_ORDER_PAYMENT_FEE = 1001;
public const ORDER_FAILED_TO_UPDATE_ORDER_TOTAL_WITH_PAYMENT_FEE = 1002;
public const ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 1003;
public const ORDER_FAILED_TO_FIND_ORDER_CART = 1004;
public const ORDER_FAILED_TO_FIND_ORDER_CUSTOMER = 1005;
public const ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 1006;
public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_ADDRESS = 1007;
public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_COUNTRY = 1008;
public const ORDER_FAILED_TO_GET_SELECTED_CARRIER_PRICE = 1009;
public const ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 1001;
public const ORDER_FAILED_TO_FIND_ORDER_CART = 1002;
public const ORDER_FAILED_TO_FIND_ORDER_CUSTOMER = 1003;
public const ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 1004;
public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_ADDRESS = 1005;
public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_COUNTRY = 1006;
public const ORDER_FAILED_TO_GET_SELECTED_CARRIER_PRICE = 1007;

//Cart error codes starts from 2000

public const CART_ALREADY_HAS_SUBSCRIPTION_PRODUCT = 2001;

//Recurring order error codes starts from 3000

public const RECURRING_ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 3001;
public const RECURRING_ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 3002;
}
88 changes: 66 additions & 22 deletions subscription/Handler/RecurringOrderHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
use Mollie\Api\Types\SubscriptionStatus;
use Mollie\Config\Config;
use Mollie\Errors\Http\HttpStatusCode;
use Mollie\Exception\OrderCreationException;
use Mollie\Exception\TransactionException;
use Mollie\Logger\PrestaLoggerInterface;
use Mollie\Repository\CarrierRepositoryInterface;
use Mollie\Repository\PaymentMethodRepositoryInterface;
use Mollie\Service\MailService;
use Mollie\Service\MollieOrderCreationService;
Expand Down Expand Up @@ -61,6 +62,10 @@ class RecurringOrderHandler
private $configuration;
/** @var RecurringOrdersProductRepositoryInterface */
private $recurringOrdersProductRepository;
/** @var CarrierRepositoryInterface */
private $carrierRepository;
/** @var PrestaLoggerInterface */
private $logger;

public function __construct(
SubscriptionApi $subscriptionApi,
Expand All @@ -75,7 +80,9 @@ public function __construct(
Shop $shop,
MailService $mailService,
ConfigurationAdapter $configuration,
RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository
RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository,
CarrierRepositoryInterface $carrierRepository,
PrestaLoggerInterface $logger
) {
$this->subscriptionApi = $subscriptionApi;
$this->subscriptionDataFactory = $subscriptionDataFactory;
Expand All @@ -90,6 +97,8 @@ public function __construct(
$this->mailService = $mailService;
$this->configuration = $configuration;
$this->recurringOrdersProductRepository = $recurringOrdersProductRepository;
$this->carrierRepository = $carrierRepository;
$this->logger = $logger;
}

public function handle(string $transactionId): string
Expand Down Expand Up @@ -130,10 +139,7 @@ public function handle(string $transactionId): string
}

/**
* @throws CouldNotHandleRecurringOrder
* @throws OrderCreationException
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
* @throws \Throwable
*/
private function createSubscription(Payment $transaction, MolRecurringOrder $recurringOrder, MollieSubscription $subscription): void
{
Expand All @@ -146,10 +152,6 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec
return;
}

$paymentMethod = $this->paymentMethodService->getPaymentMethod($transaction);

$methodName = $paymentMethod->method_name ?: Config::$methods[$transaction->method];

/** @var Cart $newCart */
$newCart = $newCart['cart'];

Expand Down Expand Up @@ -182,24 +184,66 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec

$recurringOrderProduct = new MolRecurringOrdersProduct($recurringOrder->id_mol_recurring_orders_product);

$specificPrice = $this->createSpecificPrice($recurringOrderProduct, $recurringOrder);
$subscriptionCarrierId = (int) $this->configuration->get(Config::MOLLIE_SUBSCRIPTION_ORDER_CARRIER_ID);

/** @var \Carrier|null $carrier */
$carrier = $this->carrierRepository->findOneBy([
'id_carrier' => $subscriptionCarrierId,
'active' => 1,
'deleted' => 0,
]);

$this->mollie->validateOrder(
(int) $newCart->id,
(int) $this->configuration->get(Config::MOLLIE_STATUS_AWAITING),
(float) $subscription->amount->value,
sprintf('subscription/%s', $methodName),
null,
['transaction_id' => $transaction->id],
null,
false,
$newCart->secure_key
if (!$carrier) {
throw CouldNotHandleRecurringOrder::failedToFindSelectedCarrier();
}

$newCart->setDeliveryOption(
[(int) $newCart->id_address_delivery => sprintf('%d,', (int) $carrier->id)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the sprintf really needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, verified that without sending this exact format changing delivery option won't work.

);

$newCart->update();

if (sprintf('%d,', (int) $carrier->id) !==
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could just cast into int so comma would not be needed anymore

$newCart->getDeliveryOption(null, false, false)[$newCart->id_address_delivery]
) {
throw CouldNotHandleRecurringOrder::failedToApplySelectedCarrier();
}

$specificPrice = $this->createSpecificPrice($recurringOrderProduct, $recurringOrder);

$paymentMethod = $this->paymentMethodService->getPaymentMethod($transaction);

$methodName = $paymentMethod->method_name ?: Config::$methods[$transaction->method];

try {
$this->mollie->validateOrder(
(int) $newCart->id,
(int) $this->configuration->get(Config::MOLLIE_STATUS_AWAITING),
(float) $subscription->amount->value,
sprintf('subscription/%s', $methodName),
null,
['transaction_id' => $transaction->id],
null,
false,
$newCart->secure_key
);
} catch (\Throwable $exception) {
$specificPrice->delete();

throw $exception;
}

$specificPrice->delete();

$orderId = (int) Order::getIdByCartId((int) $newCart->id);
$order = new Order($orderId);

$specificPrice->delete();
if ((float) $order->total_paid_tax_incl !== (float) $subscription->amount->value) {
$this->logger->error('Paid price is not equal to the order\'s total', [
'Paid price' => (float) $subscription->amount->value,
'Order price' => (float) $order->total_paid_tax_incl,
]);
}

$this->mollieOrderCreationService->createMolliePayment($transaction, (int) $newCart->id, $order->reference, (int) $orderId, PaymentStatus::STATUS_PAID);

Expand Down
Loading