Skip to content

Commit

Permalink
BP-2957 Set order to open on browser back, cancel group payment trans…
Browse files Browse the repository at this point in the history
…action on a new payment request & BP-2960 (#149)

* Skip giftcard pushes, let the order open

* BP-2957 Set order to open on browser back, cancel group payment transaction on a new payment request & BP-2960

* changed version

---------

Co-authored-by: Ivascu Madalin <madalin.ivascu@arnia.ro>
  • Loading branch information
harli91 and Ivascu Madalin committed Sep 25, 2023
1 parent 5be6550 commit 9efa322
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 34 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": "buckaroo/shopware6",
"description": "Buckaroo payment provider plugin for Shopware 6",
"type": "shopware-platform-plugin",
"version": "2.0.2",
"version": "2.0.3",
"license": "proprietary",
"minimum-stability": "stable",
"require": {
Expand Down
1 change: 1 addition & 0 deletions src/Handlers/AsyncPaymentHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function pay(
$paymentClass = $this->getPayment($transactionId);
$salesChannelId = $salesChannelContext->getSalesChannelId();
$paymentCode = $paymentClass->getBuckarooKey();
$this->asyncPaymentService->cancelPreviousPayments($transaction);

try {
$order = $transaction->getOrder();
Expand Down
7 changes: 7 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
<argument type="service" id="Buckaroo\Shopware6\Service\Buckaroo\ClientService"/>
</service>

<service id="Buckaroo\Shopware6\Service\CancelPaymentService">
<argument type="service" id="Buckaroo\Shopware6\Entity\Transaction\BuckarooTransactionEntityRepository"/>
<argument type="service" id="Buckaroo\Shopware6\Service\UrlService"/>
<argument type="service" id="Buckaroo\Shopware6\Service\Buckaroo\ClientService"/>
</service>

<service id="Buckaroo\Shopware6\Service\CaptureService">
<argument type="service" id="Buckaroo\Shopware6\Service\TransactionService"/>
<argument type="service" id="Buckaroo\Shopware6\Service\UrlService"/>
Expand Down Expand Up @@ -126,6 +132,7 @@
<argument type="service" id="Buckaroo\Shopware6\Service\FormatRequestParamService"/>
<argument type="service" id="Buckaroo\Shopware6\Service\PaymentStateService"/>
<argument type="service" id="Symfony\Contracts\EventDispatcher\EventDispatcherInterface"/>
<argument type="service" id="Buckaroo\Shopware6\Service\CancelPaymentService"/>
</service>

<service id="Buckaroo\Shopware6\Events\OrderStateChangeEvent">
Expand Down
50 changes: 24 additions & 26 deletions src/Resources/views/storefront/page/account/order/index.html.twig
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
{% sw_extends '@Storefront/storefront/page/account/order/index.html.twig' %}

{% block page_checkout_confirm_header %}

{% if page.errorCode == 'PAYMENT_FAILED_ERROR_490' %}
{% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
type: 'danger',
content: 'buckaroo.statuscode_failed'|trans|sw_sanitize
} %}
{% elseif page.errorCode == 'PAYMENT_FAILED_ERROR_690' %}
{% set lastPaymentTrans = page.order.transactions.last() %}
{% set sesMessage = 'buckaroo.statuscode_failed'|trans|sw_sanitize %}
{% if (
lastPaymentTrans !== null &&
lastPaymentTrans.paymentMethod !== null &&
lastPaymentTrans.paymentMethod.shortName === 'billink_payment_handler'
)
%}
{% set sesMessage = 'buckaroo.billinkRejectedMessage'|trans|sw_sanitize %}
{% endif %}
{% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
type: 'danger',
content: sesMessage
} %}
{% else %}
{{ parent() }}
{% endif %}
{% if 'PAYMENT_FAILED_ERROR_' not in page.errorCode %}
{{ parent() }}
{% if page.errorCode == 'PAYMENT_FAILED_ERROR_490' %}
{% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
type: 'danger',
content: 'buckaroo.statuscode_failed'|trans|sw_sanitize
} %}
{% elseif page.errorCode == 'PAYMENT_FAILED_ERROR_690' %}
{% set lastPaymentTrans = page.order.transactions.last() %}
{% set sesMessage = 'buckaroo.statuscode_failed'|trans|sw_sanitize %}
{% if (
lastPaymentTrans !== null &&
lastPaymentTrans.paymentMethod !== null &&
lastPaymentTrans.paymentMethod.shortName === 'billink_payment_handler'
)
%}
{% set sesMessage = 'buckaroo.billinkRejectedMessage'|trans|sw_sanitize %}
{% endif %}
{% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
type: 'danger',
content: sesMessage
} %}
{% elseif 'PAYMENT_FAILED_ERROR_' not in page.errorCode %}
{{ parent() }}
{% else %}
{{ parent() }}
{% endif %}
{% endblock %}
23 changes: 19 additions & 4 deletions src/Service/AsyncPaymentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
use Buckaroo\Shopware6\Service\StateTransitionService;
use Shopware\Core\Framework\Event\ShopwareSalesChannelEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct;
use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderCustomer\OrderCustomerEntity;

class AsyncPaymentService
{
public ClientService $clientService;

public SettingsService $settingsService;

public UrlService $urlService;
Expand All @@ -35,13 +36,15 @@ class AsyncPaymentService
* @var LoggerInterface
*/
public $logger;

public FormatRequestParamService $formatRequestParamService;

public PaymentStateService $paymentStateService;

protected EventDispatcherInterface $eventDispatcher;

protected CancelPaymentService $cancelPaymentService;

/**
* Buckaroo constructor.
*/
Expand All @@ -54,7 +57,8 @@ public function __construct(
LoggerInterface $logger,
FormatRequestParamService $formatRequestParamService,
PaymentStateService $paymentStateService,
EventDispatcherInterface $eventDispatcher
EventDispatcherInterface $eventDispatcher,
CancelPaymentService $cancelPaymentService
) {

$this->settingsService = $settingsService;
Expand All @@ -66,6 +70,7 @@ public function __construct(
$this->formatRequestParamService = $formatRequestParamService;
$this->paymentStateService = $paymentStateService;
$this->eventDispatcher = $eventDispatcher;
$this->cancelPaymentService = $cancelPaymentService;
}

/**
Expand Down Expand Up @@ -146,9 +151,19 @@ public function getCurrency(OrderEntity $order): CurrencyEntity
}
return $address;
}

public function dispatchEvent(ShopwareSalesChannelEvent $event): object
{
return $this->eventDispatcher->dispatch($event);
}


public function cancelPreviousPayments(AsyncPaymentTransactionStruct $transaction)
{
try {
$this->cancelPaymentService->cancel($transaction);
} catch (\Throwable $th) {
$this->logger->error((string)$th);
}
}
}
206 changes: 206 additions & 0 deletions src/Service/CancelPaymentService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<?php

declare(strict_types=1);

namespace Buckaroo\Shopware6\Service;

use Buckaroo\Shopware6\Buckaroo\Client;
use Buckaroo\Shopware6\Service\UrlService;
use Shopware\Core\Checkout\Order\OrderEntity;
use Symfony\Component\HttpFoundation\Request;
use Buckaroo\Shopware6\Service\Buckaroo\ClientService;
use Buckaroo\Shopware6\Buckaroo\ClientResponseInterface;
use Buckaroo\Shopware6\Helpers\Constants\ResponseStatus;
use Buckaroo\Shopware6\Helpers\Constants\IPProtocolVersion;
use Buckaroo\Shopware6\Entity\Transaction\BuckarooTransactionEntity;
use Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct;
use Buckaroo\Shopware6\Entity\Transaction\BuckarooTransactionEntityRepository;

class CancelPaymentService
{
protected BuckarooTransactionEntityRepository $buckarooTransactionEntityRepository;

protected UrlService $urlService;

protected ClientService $clientService;

public function __construct(
BuckarooTransactionEntityRepository $buckarooTransactionEntityRepository,
UrlService $urlService,
ClientService $clientService
) {
$this->buckarooTransactionEntityRepository = $buckarooTransactionEntityRepository;
$this->urlService = $urlService;
$this->clientService = $clientService;
}


/**
* Do a refund on hanging giftcards
*
* @param AsyncPaymentTransactionStruct $transactionStruct
*
* @return void
*/
public function cancel(
AsyncPaymentTransactionStruct $transactionStruct
): void {

$orderTransaction = $transactionStruct->getOrderTransaction();
$transactions = $this->buckarooTransactionEntityRepository->findByOrderId($orderTransaction->getOrderId());

foreach ($transactions as $transaction) {
if (
$transaction === null ||
$transaction->get('statuscode') != ResponseStatus::BUCKAROO_STATUSCODE_SUCCESS
) {
continue;
}

$order = $transactionStruct->getOrder();
$amount = $transaction->get('amount');
$paymentCode = $transaction->get('transaction_method');

if (
!is_scalar($amount) ||
(float)$amount <= 0 ||
!is_string($paymentCode)
) {
continue;
}


$client = $this->getClient(
'giftcards',
$order->getSalesChannelId()
)
->setAction('refund')
->setPayload(
$this->getPayload(
$order,
$transaction->get('transactions'),
$orderTransaction->getId(),
(float)$amount,
$paymentCode
)
);
$this->handleResponse(
$client->execute(),
$transaction
);
}
}

protected function handleResponse(
ClientResponseInterface $response,
BuckarooTransactionEntity $transaction
) {
if (!$response->isSuccess()) {
return;
}

$amountCredit = $transaction->get('amount_credit');

if (!is_scalar($amountCredit)) {
$amountCredit = 0;
}

$transactionAmount = $response->get('brq_amount');

if (!is_scalar($transactionAmount)) {
return;
}

$this->buckarooTransactionEntityRepository
->save(
$transaction->get('id'),
[
'amount_credit' => (string)((float)$amountCredit + (float)$transactionAmount)
],
);
}


protected function getCurrencyIso(OrderEntity $order): string
{
$currency = $order->getCurrency();
if ($currency === null) {
throw new \InvalidArgumentException('Cannot find currency on order');
}
return $currency->getIsoCode();
}

/**
* Get request parameters
*
* @param OrderEntity $order
* @param mixed $transactionKey
* @param string $orderTransactionId
* @param float $amount
* @param string $transactionKey
*
* @return array<mixed>
*/
private function getPayload(
OrderEntity $order,
$transactionKey,
string $orderTransactionId,
float $amount,
string $paymentCode
): array {

if (!is_scalar($transactionKey)) {
$transactionKey = '';
}

return [
'order' => $order->getOrderNumber(),
'invoice' => $order->getOrderNumber(),
'amountCredit' => $amount,
'currency' => $this->getCurrencyIso($order),
'pushURL' => $this->urlService->getReturnUrl('buckaroo.payment.push'),
'pushURLFailure' => $this->urlService->getReturnUrl('buckaroo.payment.push'),
'clientIP' => $this->getIp(),
'originalTransactionKey' => (string)$transactionKey,
'additionalParameters' => [
'orderTransactionId' => $orderTransactionId,
'orderId' => $order->getId(),
],
"name" => $paymentCode,
];
}



/**
* Get buckaroo client
*
* @param string $paymentCode
* @param string $salesChannelId
*
* @return Client
*/
private function getClient(string $paymentCode, string $salesChannelId): Client
{
return $this->clientService
->get($paymentCode, $salesChannelId);
}


/**
* Get client ip
*
* @param Request $request
*
* @return array<mixed>
*/
private function getIp(): array
{
$remoteIp = (Request::createFromGlobals())->getClientIp();

return [
'address' => $remoteIp,
'type' => IPProtocolVersion::getVersion($remoteIp)
];
}
}
2 changes: 1 addition & 1 deletion src/Service/PaymentStateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function finalizePayment(
* @return boolean
*/
private function isGroupTransactionCancel(Request $request): bool {
return $request->query->getString('scenario') === 'Cancellation';
return $request->query->get('scenario') === 'Cancellation';
}

/**
Expand Down
Loading

0 comments on commit 9efa322

Please sign in to comment.