Skip to content
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
8 changes: 7 additions & 1 deletion Helper/PaymentResponseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,16 @@ public function __construct(

public function formatPaymentResponse(
string $resultCode,
?array $action = null
?array $action = null,
?bool $donationTokenExists = false
): array {
switch ($resultCode) {
case self::AUTHORISED:
return [
"isFinal" => true,
"resultCode" => $resultCode,
"canDonate" => $donationTokenExists
];
case self::REFUSED:
case self::ERROR:
case self::POS_SUCCESS:
Expand Down
3 changes: 2 additions & 1 deletion Model/Api/AdyenOrderPaymentStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public function getOrderPaymentStatus(string $orderId): string

return json_encode($this->paymentResponseHandler->formatPaymentResponse(
$additionalInformation['resultCode'],
!empty($additionalInformation['action']) ? $additionalInformation['action'] : null
!empty($additionalInformation['action']) ? $additionalInformation['action'] : null,
!empty($additionalInformation['donationToken'])
));
}
}
2 changes: 1 addition & 1 deletion Model/Api/AdyenPaymentsDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function initiate(string $payload, string $orderId): string
$this->paymentResponseHandler->formatPaymentResponse(
$response['resultCode'],
$response['action'] ?? null,
$response['additionalData'] ?? null
!empty($response['donationToken'])
)
);
}
Expand Down
2 changes: 1 addition & 1 deletion Model/Api/GuestAdyenOrderPaymentStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function getOrderPaymentStatus(string $orderId, string $cartId): string
return json_encode($this->paymentResponseHandler->formatPaymentResponse(
$additionalInformation['resultCode'],
!empty($additionalInformation['action']) ? $additionalInformation['action'] : null,
!empty($additionalInformation['additionalData']) ? $additionalInformation['additionalData'] : null
!empty($additionalInformation['donationToken'])
));
}
}
53 changes: 53 additions & 0 deletions Model/GraphqlInputArgumentValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2026 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
declare(strict_types=1);

namespace Adyen\Payment\Model;

use Magento\Framework\GraphQl\Exception\GraphQlInputException;

class GraphqlInputArgumentValidator
{
/**
* Validates GraphQl input arguments
*
* Multidimensional arrays can be validated with fields separated with a dot.
*
* @param array|null $args
* @param array $requiredFields
* @return void
* @throws GraphQlInputException
*/
public function execute(?array $args, array $requiredFields): void
{
$missingFields = [];

foreach ($requiredFields as $field) {
$keys = explode('.', $field);
$value = $args;

foreach ($keys as $key) {
$value = $value[$key] ?? null;
}

if (empty($value)) {
$missingFields[] = $field;
}
}

if (!empty($missingFields)) {
throw new GraphQlInputException(
__('Required parameters "%1" are missing', implode(', ', $missingFields))
);
}
}
}
131 changes: 131 additions & 0 deletions Model/Resolver/AbstractDonationResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2026 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
declare(strict_types=1);

namespace Adyen\Payment\Model\Resolver;

use Adyen\Payment\Exception\GraphQlAdyenException;
use Adyen\Payment\Logger\AdyenLogger;
use Adyen\Payment\Model\GraphqlInputArgumentValidator;
use Adyen\Payment\Model\Sales\OrderRepository;
use Exception;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\GraphQl\Helper\Error\AggregateExceptionMessageFormatter;
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
use Magento\Sales\Api\Data\OrderInterface;

abstract class AbstractDonationResolver implements ResolverInterface
{
/**
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
* @param OrderRepository $orderRepository
* @param GraphqlInputArgumentValidator $graphqlInputArgumentValidator
* @param AdyenLogger $adyenLogger
* @param AggregateExceptionMessageFormatter $adyenGraphQlExceptionMessageFormatter
*/
public function __construct(
protected readonly MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
protected readonly OrderRepository $orderRepository,
protected readonly GraphqlInputArgumentValidator $graphqlInputArgumentValidator,
protected readonly AdyenLogger $adyenLogger,
protected readonly AggregateExceptionMessageFormatter $adyenGraphQlExceptionMessageFormatter
) { }

/**
* @return array
*/
abstract protected function getRequiredFields(): array;

/**
* @param OrderInterface $order
* @param array $args
* @param Field $field
* @param $context
* @param ResolveInfo $info
* @return array
* @throws GraphQlAdyenException
*/
abstract protected function performOperation(
OrderInterface $order,
array $args,
Field $field,
$context,
ResolveInfo $info
): array;

/**
* @return string
*/
protected function getGenericErrorMessage(): string
{
return 'An error occurred while processing the donation.';
}

/**
* @param Field $field
* @param $context
* @param ResolveInfo $info
* @param array|null $value
* @param array|null $args
* @return array
* @throws GraphQlAdyenException
* @throws GraphQlInputException
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
?array $value = null,
?array $args = null
): array {
$this->graphqlInputArgumentValidator->execute($args, $this->getRequiredFields());

try {
$quoteId = $this->maskedQuoteIdToQuoteId->execute($args['cartId']);
} catch (NoSuchEntityException $e) {
$this->adyenLogger->error(sprintf("Quote with masked ID %s not found!", $args['cartId']));
throw new GraphQlAdyenException(__($this->getGenericErrorMessage()));
}

$order = $this->orderRepository->getOrderByQuoteId($quoteId);

if (!$order) {
$this->adyenLogger->error(sprintf("Order for quote ID %s not found!", $quoteId));
throw new GraphQlAdyenException(__($this->getGenericErrorMessage()));
}

try {
return $this->performOperation($order, $args, $field, $context, $info);
} catch (LocalizedException $e) {
throw $this->adyenGraphQlExceptionMessageFormatter->getFormatted(
$e,
__($this->getGenericErrorMessage()),
$this->getGenericErrorMessage(),
$field,
$context,
$info
);
} catch (Exception $e) {
$this->adyenLogger->error(sprintf(
'%s: %s',
$this->getGenericErrorMessage(),
$e->getMessage()
));
throw new GraphQlAdyenException(__($this->getGenericErrorMessage()));
}
}
}
57 changes: 57 additions & 0 deletions Model/Resolver/DonationCampaigns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2026 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
declare(strict_types=1);

namespace Adyen\Payment\Model\Resolver;

use Adyen\Payment\Exception\GraphQlAdyenException;
use Adyen\Payment\Model\Api\AdyenDonationCampaigns;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Sales\Api\Data\OrderInterface;

class DonationCampaigns extends AbstractDonationResolver
{
/**
* @return array
*/
protected function getRequiredFields(): array
{
return [
'cartId'
];
}

/**
* @param OrderInterface $order
* @param array $args
* @param Field $field
* @param $context
* @param ResolveInfo $info
* @return array
* @throws GraphQlAdyenException|LocalizedException
*/
protected function performOperation(
OrderInterface $order,
array $args,
Field $field,
$context,
ResolveInfo $info
): array {
$adyenDonationCampaigns = ObjectManager::getInstance()->get(AdyenDonationCampaigns::class);
$campaignsResponse = $adyenDonationCampaigns->getCampaigns((int) $order->getEntityId());

return ['campaignsData' => $campaignsResponse];
}
}
72 changes: 72 additions & 0 deletions Model/Resolver/Donations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2026 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
declare(strict_types=1);

namespace Adyen\Payment\Model\Resolver;

use Adyen\Payment\Exception\GraphQlAdyenException;
use Adyen\Payment\Model\Api\AdyenDonations;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Sales\Api\Data\OrderInterface;

class Donations extends AbstractDonationResolver
{
/**
* @return array
*/
protected function getRequiredFields(): array
{
return [
'cartId',
'amount',
'amount.currency',
'returnUrl'
];
}

/**
* @param OrderInterface $order
* @param array $args
* @param Field $field
* @param $context
* @param ResolveInfo $info
* @return array
* @throws GraphQlAdyenException|LocalizedException
*/
protected function performOperation(
OrderInterface $order,
array $args,
Field $field,
$context,
ResolveInfo $info
): array {
$payloadData = [
'amount' => [
'currency' => $args['amount']['currency'],
'value' => $args['amount']['value']
],
'returnUrl' => $args['returnUrl']
];

$jsonSerializer = ObjectManager::getInstance()->get(Json::class);
$payload = $jsonSerializer->serialize($payloadData);

$adyenDonations = ObjectManager::getInstance()->get(AdyenDonations::class);
$adyenDonations->makeDonation($payload, $order);

return ['status' => true];
}
}
Loading
Loading