Skip to content

Commit

Permalink
Merge pull request #215 from mundipagg/hotfix/PAOP-68-cancel-all-char…
Browse files Browse the repository at this point in the history
…ges-if-one-fail

Cancels all charges if one of them fail in an order
  • Loading branch information
sfwill-dev authored Mar 30, 2021
2 parents dbc827b + e1966e6 commit b470abb
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 37 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "mundipagg/ecommerce-module-core",
"description": "Core component for Mundipagg e-commerce platform modules.",
"license": "MIT",
"version": "2.8.1",
"version": "2.8.2",
"authors": [
{
"name": "MundiPagg Embeddables Team",
Expand Down
149 changes: 114 additions & 35 deletions src/Kernel/Services/OrderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Mundipagg\Core\Kernel\Factories\ChargeFactory;
use Mundipagg\Core\Payment\Aggregates\Order as PaymentOrder;
use Exception;
use Mundipagg\Core\Kernel\ValueObjects\ChargeStatus;

final class OrderService
{
Expand Down Expand Up @@ -100,6 +101,49 @@ public function updateAcquirerData(Order $order)
$dataService->updateAcquirerData($order);
}

private function chargeAlreadyCanceled($charge)
{
return
$charge->getStatus()->equals(ChargeStatus::canceled()) ||
$charge->getStatus()->equals(ChargeStatus::failed());
}

private function addReceivedChargeMessages($messages, $charge, $result)
{
if (!is_null($result)) {
$messages[$charge->getMundipaggId()->getValue()] = $result;
}

return $messages;
}

private function updateChargeInOrder($order, $charge)
{
if (!empty($order)) {
$order->updateCharge($charge);
}
}

public function cancelChargesAtMundipagg(array $charges, Order $order = null)
{
$messages = [];
$APIService = new APIService();

foreach ($charges as $charge) {
if ($this->chargeAlreadyCanceled($charge)) {
continue;
}

$result = $APIService->cancelCharge($charge);

$messages = $this->addReceivedChargeMessages($messages, $charge, $result);

$this->updateChargeInOrder($order, $charge);
}

return $messages;
}

public function cancelAtMundipagg(Order $order)
{
$orderRepository = new OrderRepository();
Expand All @@ -112,21 +156,10 @@ public function cancelAtMundipagg(Order $order)
return;
}

$APIService = new APIService();

$charges = $order->getCharges();
$results = [];
foreach ($charges as $charge) {
$result = $APIService->cancelCharge($charge);
if ($result !== null) {
$results[$charge->getMundipaggId()->getValue()] = $result;
}
$order->updateCharge($charge);
}

$i18n = new LocalizationService();
$results = $this->cancelChargesAtMundipagg($order->getCharges(), $order);

if (empty($results)) {
$i18n = new LocalizationService();
$order->setStatus(OrderStatus::canceled());
$order->getPlatformOrder()->setStatus(OrderStatus::canceled());

Expand Down Expand Up @@ -155,17 +188,38 @@ public function cancelAtMundipagg(Order $order)
return;
}

$this->addMessagesToPlatformHistory($results, $order);
}

public function addMessagesToPlatformHistory($results, $order)
{
$i18n = new LocalizationService();
$history = $i18n->getDashboard("Some charges couldn't be canceled at Mundipagg. Reasons:");
$history .= "<br /><ul>";
foreach ($results as $chargeId => $reason)
{
foreach ($results as $chargeId => $reason) {
$history .= "<li>$chargeId : $reason</li>";
}
$history .= '</ul>';
$order->getPlatformOrder()->addHistoryComment($history);
$order->getPlatformOrder()->save();
}

public function addChargeMessagesToLog($platformOrder, $orderInfo, $errorMessages)
{

if (!empty($errorMessages)) {
return;
}

foreach ($errorMessages as $chargeId => $reason) {
$this->logService->orderInfo(
$platformOrder->getCode(),
"Charge $chargeId couldn't be canceled at Mundipagg. Reason: $reason",
$orderInfo
);
}
}

public function cancelAtMundipaggByPlatformOrder(PlatformOrderInterface $platformOrder)
{
$orderId = $platformOrder->getMundipaggId();
Expand Down Expand Up @@ -196,28 +250,34 @@ public function createOrderAtMundipagg(PlatformOrderInterface $platformOrder)
'Creating order.',
$orderInfo
);

//set pending
$platformOrder->setState(OrderState::stateNew());
$platformOrder->setStatus(OrderStatus::pending());

//build PaymentOrder based on platformOrder
$order = $this->extractPaymentOrderFromPlatformOrder($platformOrder);
$paymentOrder = $this->extractPaymentOrderFromPlatformOrder($platformOrder);

$i18n = new LocalizationService();

//Send through the APIService to mundipagg
$apiService = new APIService();
$response = $apiService->createOrder($order);
$response = $apiService->createOrder($paymentOrder);

$originalResponse = $response;
$forceCreateOrder = MPSetup::getModuleConfiguration()->isCreateOrderEnabled();

if (!$forceCreateOrder && !$this->checkResponseStatus($response)) {
if (!$forceCreateOrder && !$this->wasOrderChargedSuccessfully($response)) {
$this->logService->orderInfo(
$platformOrder->getCode(),
"Can't create order. - Force Create Order: {$forceCreateOrder} | Order or charge status failed",
$orderInfo
);

$charges = $this->createChargesFromResponse($response);
$errorMessages = $this->cancelChargesAtMundipagg($charges);

$this->addChargeMessagesToLog($platformOrder, $orderInfo, $errorMessages);

$this->persistListChargeFailed($response);

$message = $i18n->getDashboard("Can't create order.");
Expand All @@ -227,16 +287,15 @@ public function createOrderAtMundipagg(PlatformOrderInterface $platformOrder)
$platformOrder->save();

$orderFactory = new OrderFactory();
$response = $orderFactory->createFromPostData($response);

$response->setPlatformOrder($platformOrder);
$order = $orderFactory->createFromPostData($response);
$order->setPlatformOrder($platformOrder);

$handler = $this->getResponseHandler($response);
$handler->handle($response, $order);
$handler = $this->getResponseHandler($order);
$handler->handle($order, $paymentOrder);

$platformOrder->save();

if ($forceCreateOrder && !$this->checkResponseStatus($originalResponse)) {
if (!$this->wasOrderChargedSuccessfully($response)) {
$this->logService->orderInfo(
$platformOrder->getCode(),
"Can't create order. - Force Create Order: {$forceCreateOrder} | Order or charge status failed",
Expand All @@ -246,7 +305,7 @@ public function createOrderAtMundipagg(PlatformOrderInterface $platformOrder)
throw new \Exception($message, 400);
}

return [$response];
return [$order];
} catch (\Exception $e) {
$this->logService->orderInfo(
$platformOrder->getCode(),
Expand Down Expand Up @@ -308,7 +367,7 @@ public function extractPaymentOrderFromPlatformOrder(
$message,
$orderInfo
);
throw new \Exception($message,400);
throw new \Exception($message, 400);
}

$items = $platformOrder->getItemCollection();
Expand Down Expand Up @@ -337,17 +396,21 @@ public function getOrderInfo(PlatformOrderInterface $platformOrder)
return $orderInfo;
}

private function responseHasChargesAndFailed($response)
{
return !isset($response['status']) ||
!isset($response['charges']) ||
$response['status'] == 'failed';
}

/**
* @param $response
* @return boolean
*/
private function checkResponseStatus($response)
private function wasOrderChargedSuccessfully($response)
{
if (
!isset($response['status']) ||
!isset($response['charges']) ||
$response['status'] == 'failed'
) {

if ($this->responseHasChargesAndFailed($response)) {
return false;
}

Expand All @@ -371,17 +434,33 @@ private function persistListChargeFailed($response)
return;
}

$chargeFactory = new ChargeFactory();
$charges = $this->createChargesFromResponse($response);
$chargeService = new ChargeService();

foreach ($charges as $charge) {
$chargeService->save($charge);
}
}

private function createChargesFromResponse($response)
{
if (empty($response['charges'])) {
return;
}

$charges = [];
$chargeFactory = new ChargeFactory();

foreach ($response['charges'] as $chargeResponse) {
$order = ['order' => ['id' => $response['id']]];
$charge = $chargeFactory->createFromPostData(
array_merge($chargeResponse, $order)
);

$chargeService->save($charge);
$charges[] = $charge;
}

return $charges;
}

/**
Expand Down
Loading

0 comments on commit b470abb

Please sign in to comment.