We will be off from 27/1 (Monday) to 31/1 (Friday) (GMT +7) for our Tet Holiday (Lunar New Year) in our country

Commit db1a09f9 authored by Rik ter Beek's avatar Rik ter Beek

Fixes #72 add support for split payments and split refund strategy

parent 5ad22740
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Api\Data;
interface OrderPaymentInterface
{
/**#@+
* Constants for keys of data array. Identical to the name of the getter in snake case.
*/
/*
* Entity ID.
*/
const ENTITY_ID = 'entity_id';
/*
* Pspreference.
*/
const PSPREFRENCE = 'pspreference';
/*
* Merchantreference
*/
const MERCHANT_REFERENCE = 'merchant_reference';
/*
* payment_id
*/
const PAYMENT_ID = 'payment_id';
/*
* Paymentmethod
*/
const PAYMENT_METHOD = 'payment_method';
/*
* Amount
*/
const AMOUNT = 'amount';
/*
* Amount
*/
const TOTAL_REFUNDED = 'total_refunded';
/*
* Created-at timestamp.
*/
const CREATED_AT = 'created_at';
/*
* Updated-at timestamp.
*/
const UPDATED_AT = 'updated_at';
/**
* Gets the ID for the payment.
*
* @return int|null Entity ID.
*/
public function getEntityId();
/**
* Sets entity ID.
*
* @param int $entityId
* @return $this
*/
public function setEntityId($entityId);
/**
* Gets the Pspreference for the payment.
*
* @return int|null Pspreference.
*/
public function getPspreference();
/**
* Sets Pspreference.
*
* @param string $pspreference
* @return $this
*/
public function setPspreference($pspreference);
/**
* Gets the Merchantreference for the payment.
*
* @return int|null MerchantReference.
*/
public function getMerchantReference();
/**
* Sets MerchantReference.
*
* @param string $merchantReference
* @return $this
*/
public function setMerchantReference($merchantReference);
/**
* Gets the PaymentId for the payment.
*
* @return int|null PaymentId.
*/
public function getPaymentId();
/**
* Sets PaymentId.
*
* @param string $paymentId
* @return $this
*/
public function setPaymentId($paymentId);
/**
* Gets the Paymentmethod for the payment.
*
* @return int|null PaymentMethod.
*/
public function getPaymentMethod();
/**
* Sets PaymentMethod.
*
* @param string $paymentMethod
* @return $this
*/
public function setPaymentMethod($paymentMethod);
/**
* Gets the Amount for the payment.
*
* @return int|null Amount.
*/
public function getAmount();
/**
* Sets Amount.
*
* @param string $amount
* @return $this
*/
public function setAmount($amount);
/**
* Gets the TotalRefunded for the payment.
*
* @return int|null TotalRefunded.
*/
public function getTotalRefunded();
/**
* Sets Total Refunded.
*
* @param string $totalRefunded
* @return $this
*/
public function setTotalRefunded($totalRefunded);
/**
* Gets the created-at timestamp for the payment.
*
* @return string|null Created-at timestamp.
*/
public function getCreatedAt();
/**
* Sets the created-at timestamp for the payment.
*
* @param string $createdAt timestamp
* @return $this
*/
public function setCreatedAt($createdAt);
/**
* Gets the updated-at timestamp for the payment.
*
* @return string|null Updated-at timestamp.
*/
public function getUpdatedAt();
/**
* Sets the updated-at timestamp for the payment.
*
* @param string $timestamp
* @return $this
*/
public function setUpdatedAt($timestamp);
}
\ No newline at end of file
...@@ -82,17 +82,20 @@ class TransactionRefund implements ClientInterface ...@@ -82,17 +82,20 @@ class TransactionRefund implements ClientInterface
*/ */
public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject) public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject)
{ {
$request = $transferObject->getBody(); $requests = $transferObject->getBody();
$responses = [];
// call lib foreach ($requests as $request) {
$service = new \Adyen\Service\Modification($this->_client);
try { // call lib
$response = $service->refund($request); $service = new \Adyen\Service\Modification($this->_client);
} catch(\Adyen\AdyenException $e) {
$response = null;
}
return $response; try {
$responses[] = $service->refund($request);
} catch(\Adyen\AdyenException $e) {
$responses[] = null;
}
}
return $responses;
} }
} }
\ No newline at end of file
...@@ -36,14 +36,23 @@ class RefundDataBuilder implements BuilderInterface ...@@ -36,14 +36,23 @@ class RefundDataBuilder implements BuilderInterface
*/ */
private $adyenHelper; private $adyenHelper;
/**
* @var \Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory
*/
private $orderPaymentCollectionFactory;
/** /**
* CaptureDataBuilder constructor. * CaptureDataBuilder constructor.
* *
* @param \Adyen\Payment\Helper\Data $adyenHelper * @param \Adyen\Payment\Helper\Data $adyenHelper
*/ */
public function __construct(\Adyen\Payment\Helper\Data $adyenHelper) public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $orderPaymentCollectionFactory
)
{ {
$this->adyenHelper = $adyenHelper; $this->adyenHelper = $adyenHelper;
$this->orderPaymentCollectionFactory = $orderPaymentCollectionFactory;
} }
/** /**
...@@ -52,26 +61,93 @@ class RefundDataBuilder implements BuilderInterface ...@@ -52,26 +61,93 @@ class RefundDataBuilder implements BuilderInterface
*/ */
public function build(array $buildSubject) public function build(array $buildSubject)
{ {
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */ /** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject); $paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject); $amount = \Magento\Payment\Gateway\Helper\SubjectReader::readAmount($buildSubject);
$order = $paymentDataObject->getOrder();
$payment = $paymentDataObject->getPayment(); $payment = $paymentDataObject->getPayment();
$pspReference = $payment->getCcTransId(); $pspReference = $payment->getCcTransId();
$currency = $payment->getOrder()->getOrderCurrencyCode(); $currency = $payment->getOrder()->getOrderCurrencyCode();
$storeId = $order->getStoreId();
$merchantAccount = $this->adyenHelper->getAdyenAbstractConfigData("merchant_account", $storeId);
$grandTotal = $payment->getOrder()->getGrandTotal();
// check if it contains a split payment
$orderPaymentCollection = $this->orderPaymentCollectionFactory->create();
// partial refund if multiple payments check refund strategy
if ($orderPaymentCollection->getSize() > 1) {
$refundStrategy = $this->adyenHelper->getAdyenAbstractConfigData(
'split_payments_refund_strategy',
$order->getStoreId()
);
$ratio = null;
if ($refundStrategy == "1") {
// Refund in ascending order
$orderPaymentCollection->addPaymentFilterAscending($payment->getId());
} elseif ($refundStrategy == "2") {
// Refund in descending order
$orderPaymentCollection->addPaymentFilterDescending($payment->getId());
} elseif ($refundStrategy == "3") {
// refund based on ratio
$ratio = $amount / $grandTotal;
$orderPaymentCollection->addPaymentFilterAscending($payment->getId());
}
// loop over payment methods and refund them all
$result = [];
foreach ($orderPaymentCollection as $splitPayment) {
// could be that not all the split payments need a refund
if ($amount > 0) {
if ($ratio) {
// refund based on ratio calculate refund amount
$modificationAmount = $ratio * ($splitPayment->getAmount() - $splitPayment->getRefundedAmount());
} else {
// total authorised amount of the split payment
$splitPaymentAmount = $splitPayment->getAmount() - $splitPayment->getRefundedAmount();
// if refunded amount is greather then split payment amount do a full refund
if ($amount >= $splitPaymentAmount) {
$modificationAmount = $splitPaymentAmount;
} else {
$modificationAmount = $amount;
}
// update amount with rest of the available amount
$amount = $amount - $splitPaymentAmount;
}
$modificationAmountObject = [
'currency' => $currency,
'value' => $this->adyenHelper->formatAmount($modificationAmount, $currency)
];
//format the amount to minor units $result[] = [
$amount = $this->adyenHelper->formatAmount($amount, $currency); "modificationAmount" => $modificationAmountObject,
"reference" => $payment->getOrder()->getIncrementId(),
"originalReference" => $splitPayment->getPspreference(),
"merchantAccount" => $merchantAccount
];
}
}
} else {
//format the amount to minor units
$amount = $this->adyenHelper->formatAmount($amount, $currency);
$modificationAmount = ['currency' => $currency, 'value' => $amount];
$modificationAmount = ['currency' => $currency, 'value' => $amount]; $result = [
[
"modificationAmount" => $modificationAmount,
"reference" => $payment->getOrder()->getIncrementId(),
"originalReference" => $pspReference,
"merchantAccount" => $merchantAccount
]
];
}
$result = [
"modificationAmount" => $modificationAmount,
"reference" => $payment->getOrder()->getIncrementId(),
"originalReference" => $pspReference
];
return $result; return $result;
} }
} }
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Response;
use Magento\Payment\Gateway\Response\HandlerInterface;
class PaymentCommentHistoryRefundHandler implements HandlerInterface
{
/**
* @param array $handlingSubject
* @param array $response
* @return $this
*/
public function handle(array $handlingSubject, array $response)
{
$payment = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($handlingSubject);
/** @var OrderPaymentInterface $payment */
$payment = $payment->getPayment();
foreach ($response as $singleResponse) {
if (isset($singleResponse['resultCode'])) {
$responseCode = $singleResponse['resultCode'];
} else {
// try to get response from response key (used for modifications
if (isset($singleResponse['response'])) {
$responseCode = $singleResponse['response'];
} else {
$responseCode = "";
}
}
if (isset($singleResponse['pspReference'])) {
$pspReference = $singleResponse['pspReference'];
} else {
$pspReference = "";
}
$type = 'Adyen Result response:';
$comment = __('%1 <br /> authResult: %2 <br /> pspReference: %3 ',
$type, $responseCode, $pspReference);
if ($responseCode) {
$payment->getOrder()->setAdyenResulturlEventCode($responseCode);
}
$payment->getOrder()->addStatusHistoryComment($comment);
}
return $this;
}
}
...@@ -38,11 +38,13 @@ class PaymentRefundDetailsHandler implements HandlerInterface ...@@ -38,11 +38,13 @@ class PaymentRefundDetailsHandler implements HandlerInterface
/** @var OrderPaymentInterface $payment */ /** @var OrderPaymentInterface $payment */
$payment = $payment->getPayment(); $payment = $payment->getPayment();
// set pspReference as lastTransId only! foreach ($response as $singleResponse) {
$payment->setLastTransId($response['pspReference']); // set pspReference as lastTransId only!
$payment->setLastTransId($singleResponse['pspReference']);
}
/** /**
* close current transaction because you have capture the goods * close current transaction because you have refunded the goods
* but only on full refund close the authorisation * but only on full refund close the authorisation
*/ */
$payment->setIsTransactionClosed(true); $payment->setIsTransactionClosed(true);
......
...@@ -33,16 +33,19 @@ class RefundResponseValidator extends AbstractValidator ...@@ -33,16 +33,19 @@ class RefundResponseValidator extends AbstractValidator
*/ */
public function validate(array $validationSubject) public function validate(array $validationSubject)
{ {
$response = \Magento\Payment\Gateway\Helper\SubjectReader::readResponse($validationSubject); $responses = \Magento\Payment\Gateway\Helper\SubjectReader::readResponse($validationSubject);
$isValid = true; $isValid = true;
$errorMessages = []; $errorMessages = [];
if ($response['response'] != '[refund-received]') { foreach ($responses as $response) {
$errorMsg = __('Error with refund'); if ($response['response'] != '[refund-received]') {
$this->_logger->critical($errorMsg); $errorMsg = __('Error with refund');
$errorMessages[] = $errorMsg; $this->_logger->critical($errorMsg);
$errorMessages[] = $errorMsg;
}
} }
return $this->createResult($isValid, $errorMessages); return $this->createResult($isValid, $errorMessages);
} }
} }
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Config\Source;
class SplitPaymentRefundStrategy implements \Magento\Framework\Option\ArrayInterface
{
const REFUND_FIRST_PAYEMENT_FIRST = 1;
const REFUND_LAST_PAYEMENT_FIRST = 2;
const REFUND_ON_RATIO = 3;
/**
* @return array
*/
public function toOptionArray()
{
return $this->getSplitPaymentRefundStrategies();
}
/**
* @return array
*/
public function getSplitPaymentRefundStrategies()
{
return [
self::REFUND_FIRST_PAYEMENT_FIRST => __('Refund from first payment first'),
self::REFUND_LAST_PAYEMENT_FIRST => 'Refund from last payment first',
self::REFUND_ON_RATIO => __('refund based on ratio')
];
}
}
...@@ -148,6 +148,16 @@ class Cron ...@@ -148,6 +148,16 @@ class Cron
*/ */
protected $_fraudManualReview; protected $_fraudManualReview;
/**
* @var Order\PaymentFactory
*/
protected $_adyenOrderPaymentFactory;
/**
* @var Resource\Order\Payment\CollectionFactory
*/
protected $_adyenOrderPaymentCollectionFactory;
/** /**
* Cron constructor. * Cron constructor.
* *
...@@ -172,7 +182,9 @@ class Cron ...@@ -172,7 +182,9 @@ class Cron
\Magento\Framework\DB\TransactionFactory $transactionFactory, \Magento\Framework\DB\TransactionFactory $transactionFactory,
\Adyen\Payment\Model\Billing\AgreementFactory $billingAgreementFactory, \Adyen\Payment\Model\Billing\AgreementFactory $billingAgreementFactory,
\Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory, \Adyen\Payment\Model\Resource\Billing\Agreement\CollectionFactory $billingAgreementCollectionFactory,
\Adyen\Payment\Model\Api\PaymentRequest $paymentRequest \Adyen\Payment\Model\Api\PaymentRequest $paymentRequest,
\Adyen\Payment\Model\Order\PaymentFactory $adyenOrderPaymentFactory,
\Adyen\Payment\Model\Resource\Order\Payment\CollectionFactory $adyenOrderPaymentCollectionFactory
) { ) {
$this->_scopeConfig = $scopeConfig; $this->_scopeConfig = $scopeConfig;
$this->_adyenLogger = $adyenLogger; $this->_adyenLogger = $adyenLogger;
...@@ -184,6 +196,8 @@ class Cron ...@@ -184,6 +196,8 @@ class Cron
$this->_billingAgreementFactory = $billingAgreementFactory; $this->_billingAgreementFactory = $billingAgreementFactory;
$this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory; $this->_billingAgreementCollectionFactory = $billingAgreementCollectionFactory;
$this->_adyenPaymentRequest = $paymentRequest; $this->_adyenPaymentRequest = $paymentRequest;
$this->_adyenOrderPaymentFactory = $adyenOrderPaymentFactory;
$this->_adyenOrderPaymentCollectionFactory = $adyenOrderPaymentCollectionFactory;
} }
/** /**
...@@ -194,8 +208,6 @@ class Cron ...@@ -194,8 +208,6 @@ class Cron
{ {
$this->_order = null; $this->_order = null;
$this->_adyenLogger->addAdyenNotificationCronjob("START OF THE CRONJOB");
// execute notifications from 2 minute or earlier because order could not yet been created by magento // execute notifications from 2 minute or earlier because order could not yet been created by magento
$dateStart = new \DateTime(); $dateStart = new \DateTime();
$dateStart->modify('-5 day'); $dateStart->modify('-5 day');
...@@ -209,8 +221,13 @@ class Cron ...@@ -209,8 +221,13 @@ class Cron
$notifications->addFieldToFilter('created_at', $dateRange); $notifications->addFieldToFilter('created_at', $dateRange);
// loop over the notifications // loop over the notifications
$count = 0;
foreach ($notifications as $notification) { foreach ($notifications as $notification) {
$this->_adyenLogger->addAdyenNotificationCronjob(
sprintf("Processing notification %s", $notification->getEntityId())
);
// log the executed notification // log the executed notification
$this->_adyenLogger->addAdyenNotificationCronjob(print_r($notification->debug(), 1)); $this->_adyenLogger->addAdyenNotificationCronjob(print_r($notification->debug(), 1));
...@@ -288,8 +305,15 @@ class Cron ...@@ -288,8 +305,15 @@ class Cron
$notification->setDone(true); $notification->setDone(true);
$notification->setUpdatedAt($dateEnd); $notification->setUpdatedAt($dateEnd);
$notification->save(); $notification->save();
$this->_adyenLogger->addAdyenNotificationCronjob(
sprintf("Notification %s is processed", $notification->getEntityId())
);
++$count;
}
if ($count > 0) {
$this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Cronjob updated %s notification(s)", $count));
} }
$this->_adyenLogger->addAdyenNotificationCronjob("END OF THE CRONJOB");
} }
/** /**
...@@ -990,46 +1014,29 @@ class Cron ...@@ -990,46 +1014,29 @@ class Cron
// validate if amount is total amount // validate if amount is total amount
$orderCurrencyCode = $this->_order->getOrderCurrencyCode(); $orderCurrencyCode = $this->_order->getOrderCurrencyCode();
$orderAmount = (int) $this->_adyenHelper->formatAmount($this->_order->getGrandTotal(), $orderCurrencyCode); $paymentObj = $this->_order->getPayment();
$amount = $this->_adyenHelper->originalAmount($this->_value, $orderCurrencyCode);
if ($this->_isTotalAmount($orderAmount)) {
// add to order payment
$date = new \DateTime();
$this->_adyenOrderPaymentFactory->create()
->setPspreference($this->_pspReference)
->setMerchantReference($this->_merchantReference)
->setPaymentId($paymentObj->getId())
->setPaymentMethod($this->_paymentMethod)
->setAmount($amount)
->setTotalRefunded(0)
->setCreatedAt($date)
->setUpdatedAt($date)
->save();
if ($this->_isTotalAmount($paymentObj->getEntityId(), $orderCurrencyCode)) {
$this->_createInvoice(); $this->_createInvoice();
} else { } else {
$this->_adyenLogger->addAdyenNotificationCronjob('This is a partial AUTHORISATION'); $this->_adyenLogger->addAdyenNotificationCronjob(
'This is a partial AUTHORISATION and the full amount is not reached'
// Check if this is the first partial authorisation or if there is already been an authorisation );
$paymentObj = $this->_order->getPayment();
$authorisationAmount = $paymentObj->getAdyenAuthorisationAmount();
if ($authorisationAmount != "") {
$this->_adyenLogger->addAdyenNotificationCronjob(
'There is already a partial AUTHORISATION received check if this combined with the ' .
'previous amounts match the total amount of the order'
);
$authorisationAmount = (int) $authorisationAmount;
$currentValue = (int) $this->_value;
$totalAuthorisationAmount = $authorisationAmount + $currentValue;
// update amount in column
$paymentObj->setAdyenAuthorisationAmount($totalAuthorisationAmount);
if ($totalAuthorisationAmount == $orderAmount) {
$this->_adyenLogger->addAdyenNotificationCronjob(
'The full amount is paid. This is the latest AUTHORISATION notification. Create the invoice'
);
$this->_createInvoice();
} else {
// this can be multiple times so use envenData as unique key
$this->_adyenLogger->addAdyenNotificationCronjob(
'The full amount is not reached. Wait for the next AUTHORISATION notification. ' .
'The current amount that is authorized is:' . $totalAuthorisationAmount
);
}
} else {
$this->_adyenLogger->addAdyenNotificationCronjob(
'This is the first partial AUTHORISATION save this into the adyen_authorisation_amount field'
);
$paymentObj->setAdyenAuthorisationAmount($this->_value);
}
} }
} }
...@@ -1196,22 +1203,36 @@ class Cron ...@@ -1196,22 +1203,36 @@ class Cron
* @param $orderAmount * @param $orderAmount
* @return bool * @return bool
*/ */
protected function _isTotalAmount($orderAmount) protected function _isTotalAmount($paymentId, $orderCurrencyCode)
{ {
$this->_adyenLogger->addAdyenNotificationCronjob( $this->_adyenLogger->addAdyenNotificationCronjob(
'Validate if AUTHORISATION notification has the total amount of the order' 'Validate if AUTHORISATION notification has the total amount of the order'
); );
$value = (int)$this->_value;
if ($value == $orderAmount) { // get total amount of the order
$this->_adyenLogger->addAdyenNotificationCronjob('AUTHORISATION has the full amount'); $grandTotal = (int) $this->_adyenHelper->formatAmount($this->_order->getGrandTotal(), $orderCurrencyCode);
return true;
} else { // check if total amount of the order is authorised
$this->_adyenLogger->addAdyenNotificationCronjob( $res = $this->_adyenOrderPaymentCollectionFactory
'This is a partial AUTHORISATION, the amount is ' . $this->_value ->create()
); ->getTotalAmount($paymentId);
return false;
if($res && isset($res[0]) && is_array($res[0])) {
$amount = $res[0]['total_amount'];
$orderAmount = $this->_adyenHelper->formatAmount($amount, $orderCurrencyCode);
$this->_adyenLogger->addAdyenNotificationCronjob(sprintf('The grandtotal amount is %s and the total order amount that is authorised is: %s', $grandTotal, $orderAmount));
if ($grandTotal == $orderAmount) {
$this->_adyenLogger->addAdyenNotificationCronjob('AUTHORISATION has the full amount');
return true;
} else {
$this->_adyenLogger->addAdyenNotificationCronjob(
'This is a partial AUTHORISATION, the amount is ' . $this->_value
);
return false;
}
} }
return false;
} }
/** /**
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
namespace Adyen\Payment\Model; namespace Adyen\Payment\Model;
use Adyen\Payment\Api\Data\NotificationInterface; use Adyen\Payment\Api\Data\NotificationInterface;
use Magento\Framework\DataObject\IdentityInterface;
class Notification extends \Magento\Framework\Model\AbstractModel class Notification extends \Magento\Framework\Model\AbstractModel
implements NotificationInterface implements NotificationInterface
...@@ -92,6 +91,23 @@ class Notification extends \Magento\Framework\Model\AbstractModel ...@@ -92,6 +91,23 @@ class Notification extends \Magento\Framework\Model\AbstractModel
$result = $this->getResource()->getNotification($pspReference, $eventCode, $success); $result = $this->getResource()->getNotification($pspReference, $eventCode, $success);
return (empty($result)) ? false : true; return (empty($result)) ? false : true;
} }
/**
* @return mixed
*/
public function getEntityId()
{
return $this->getData(self::ENTITY_ID);
}
/**
* @param int $entityId
* @return $this
*/
public function setEntityId($entityId)
{
return $this->setData(self::ENTITY_ID, $entityId);
}
/** /**
* Gets the Pspreference for the notification. * Gets the Pspreference for the notification.
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Order;
use Adyen\Payment\Api\Data\OrderPaymentInterface;
class Payment extends \Magento\Framework\Model\AbstractModel
implements OrderPaymentInterface
{
/**
* Notification constructor.
*
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}
/**
* Initialize resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('Adyen\Payment\Model\Resource\Order\Payment');
}
/**
* @return mixed
*/
public function getPspreference()
{
return $this->getData(self::PSPREFRENCE);
}
/**
* @param string $pspreference
* @return $this
*/
public function setPspreference($pspreference)
{
return $this->setData(self::PSPREFRENCE, $pspreference);
}
/**
* @return mixed
*/
public function getMerchantReference()
{
return $this->getData(self::MERCHANT_REFERENCE);
}
/**
* @param string $merchantReference
* @return $this
*/
public function setMerchantReference($merchantReference)
{
return $this->setData(self::MERCHANT_REFERENCE, $merchantReference);
}
/**
* @return mixed
*/
public function getPaymentId()
{
return $this->getData(self::PAYMENT_ID);
}
/**
* @param string $paymentId
* @return $this
*/
public function setPaymentId($paymentId)
{
return $this->setData(self::PAYMENT_ID, $paymentId);
}
/**
* @return mixed
*/
public function getPaymentMethod()
{
return $this->getData(self::PAYMENT_METHOD);
}
/**
* @param string $paymentMethod
* @return $this
*/
public function setPaymentMethod($paymentMethod)
{
return $this->setData(self::PAYMENT_METHOD, $paymentMethod);
}
/**
* @return mixed
*/
public function getAmount()
{
return $this->getData(self::AMOUNT);
}
/**
* @param string $amount
* @return $this
*/
public function setAmount($amount)
{
return $this->setData(self::AMOUNT, $amount);
}
/**
* @return mixed
*/
public function getTotalRefunded()
{
return $this->getData(self::TOTAL_REFUNDED);
}
/**
* @param string $totalRefunded
* @return $this
*/
public function setTotalRefunded($totalRefunded)
{
return $this->setData(self::TOTAL_REFUNDED, $totalRefunded);
}
/**
* @return mixed
*/
public function getCreatedAt()
{
return $this->getData(self::CREATED_AT);
}
/**
* @param string $createdAt
* @return $this
*/
public function setCreatedAt($createdAt)
{
return $this->setData(self::CREATED_AT, $createdAt);
}
/**
* @return mixed
*/
public function getUpdatedAt()
{
return $this->getData(self::UPDATED_AT);
}
/**
* @param string $updatedAt
* @return $this
*/
public function setUpdatedAt($updatedAt)
{
return $this->setData(self::UPDATED_AT, $updatedAt);
}
}
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Resource\Order;
class Payment extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
/**
* Construct
*/
public function _construct()
{
$this->_init('adyen_order_payment', 'entity_id');
}
}
\ No newline at end of file
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model\Resource\Order\Payment;
/**
* Billing agreements resource collection
*/
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
/**
* Collection initialization
*
* @return void
*/
protected function _construct()
{
$this->_init('Adyen\Payment\Model\Order\Payment', 'Adyen\Payment\Model\Resource\Order\Payment');
}
/**
* @param integer $paymentId
* @return array
*/
public function getTotalAmount($paymentId)
{
$connection = $this->getConnection();
$sumCond = new \Zend_Db_Expr("SUM(adyen_order_payment.{$connection->quoteIdentifier(\Adyen\Payment\Model\Order\Payment::AMOUNT)})");
$select = $connection->select()->from(
['adyen_order_payment' => $this->getTable('adyen_order_payment')],
['total_amount' => $sumCond]
)->where(
'payment_id = :payment_id'
);
return $connection->fetchAll($select, [':payment_id' => $paymentId]);
}
/**
* @param string $paymentId
* @return $this
*/
public function addPaymentFilterAscending($paymentId)
{
$this->addFieldToFilter('payment_id', $paymentId);
$this->getSelect()->order(['created_at ASC']);
return $this;
}
/**
* @param string $paymentId
* @return $this
*/
public function addPaymentFilterDescending($paymentId)
{
$this->addFieldToFilter('payment_id', $paymentId);
$this->getSelect()->order(['created_at DESC']);
return $this;
}
}
...@@ -33,6 +33,10 @@ use Magento\Framework\Setup\SchemaSetupInterface; ...@@ -33,6 +33,10 @@ use Magento\Framework\Setup\SchemaSetupInterface;
*/ */
class UpgradeSchema implements UpgradeSchemaInterface class UpgradeSchema implements UpgradeSchemaInterface
{ {
const ADYEN_ORDER_PAYMENT = 'adyen_order_payment';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -48,6 +52,10 @@ class UpgradeSchema implements UpgradeSchemaInterface ...@@ -48,6 +52,10 @@ class UpgradeSchema implements UpgradeSchemaInterface
$this->updateSchemaVersion1002($setup); $this->updateSchemaVersion1002($setup);
} }
if (version_compare($context->getVersion(), '1.4.5.1', '<')) {
$this->updateSchemaVersion1451($setup);
}
$setup->endSetup(); $setup->endSetup();
} }
...@@ -100,4 +108,107 @@ class UpgradeSchema implements UpgradeSchemaInterface ...@@ -100,4 +108,107 @@ class UpgradeSchema implements UpgradeSchemaInterface
$setup->getTable('paypal_billing_agreement'), 'agreement_data', $adyenAgreementDataColumn $setup->getTable('paypal_billing_agreement'), 'agreement_data', $adyenAgreementDataColumn
); );
} }
/**
* @param SchemaSetupInterface $setup
*/
public function updateSchemaVersion1451(SchemaSetupInterface $setup)
{
/**
* Create table 'adyen_order_payment'
*/
$table = $setup->getConnection()
->newTable($setup->getTable(self::ADYEN_ORDER_PAYMENT))
->addColumn(
'entity_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Adyen Payment ID'
)
->addColumn(
'pspreference',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['unsigned' => true, 'nullable' => false],
'Pspreference'
)
->addColumn(
'merchant_reference',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['unsigned' => true, 'nullable' => false],
'Merchant Reference'
)
->addColumn(
'payment_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
11,
['unsigned' => true, 'nullable' => false],
'Order Payment Id'
)
->addColumn(
'payment_method',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['unsigned' => true, 'nullable' => true],
'Payment Method'
)
->addColumn(
'amount',
\Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
'12,4',
['unsigned' => true, 'nullable' => false],
'Amount'
)
->addColumn(
'total_refunded',
\Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
'12,4',
['unsigned' => true, 'nullable' => false],
'Total Refunded'
)
->addColumn(
'created_at',
Table::TYPE_DATETIME,
null,
['nullable' => false],
'Created at'
)
->addColumn(
'updated_at',
Table::TYPE_DATETIME,
null,
['nullable' => false],
'Updated at'
)
->addIndex(
$setup->getIdxName(
self::ADYEN_ORDER_PAYMENT,
['pspreference'],
\Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
),
['pspreference'],
['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
)
->addForeignKey(
$setup->getFkName(
self::ADYEN_ORDER_PAYMENT,
'payment_id',
'sales_order_payment',
'entity_id'
),
'payment_id',
$setup->getTable('sales_order_payment'),
'entity_id',
\Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
)
->setComment('Adyen Order Payment');
$setup->getConnection()->createTable($table);
}
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "adyen/module-payment", "name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.", "description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module", "type": "magento2-module",
"version": "1.4.5", "version": "1.4.5.1",
"license": [ "license": [
"OSL-3.0", "OSL-3.0",
"AFL-3.0" "AFL-3.0"
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
<include path="Adyen_Payment::system/adyen_billing_agreements.xml"/> <include path="Adyen_Payment::system/adyen_billing_agreements.xml"/>
<include path="Adyen_Payment::system/adyen_checkout_experience.xml"/> <include path="Adyen_Payment::system/adyen_checkout_experience.xml"/>
<include path="Adyen_Payment::system/adyen_manual_review.xml"/> <include path="Adyen_Payment::system/adyen_manual_review.xml"/>
<include path="Adyen_Payment::system/adyen_split_payment.xml"/>
<include path="Adyen_Payment::system/adyen_cc.xml"/> <include path="Adyen_Payment::system/adyen_cc.xml"/>
<include path="Adyen_Payment::system/adyen_oneclick.xml"/> <include path="Adyen_Payment::system/adyen_oneclick.xml"/>
<include path="Adyen_Payment::system/adyen_hpp.xml"/> <include path="Adyen_Payment::system/adyen_hpp.xml"/>
......
<?xml version="1.0"?>
<!--
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="adyen_split_payment" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label><![CDATA[Advanced: Split Payment]]></label>
<frontend_model>Magento\Config\Block\System\Config\Form\Fieldset</frontend_model>
<comment>
<![CDATA[
<p>
It is possible to do split payments with GiftCards please configure here what refund strategie you want to use
</p>
]]>
</comment>
<field id="split_payments_refund_strategy" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Refund Strategy</label>
<tooltip>Only relevant if you accept giftcards on Adyen platform</tooltip>
<source_model>Adyen\Payment\Model\Config\Source\SplitPaymentRefundStrategy</source_model>
<config_path>payment/adyen_abstract/split_payments_refund_strategy</config_path>
</field>
</group>
</include>
\ No newline at end of file
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<debug>1</debug> <debug>1</debug>
<title_renderer>title_image</title_renderer> <title_renderer>title_image</title_renderer>
<sepa_flow>sale</sepa_flow> <sepa_flow>sale</sepa_flow>
<split_payments_refund_strategy>1</split_payments_refund_strategy>
<group>adyen</group> <group>adyen</group>
</adyen_abstract> </adyen_abstract>
<adyen_cc> <adyen_cc>
......
...@@ -509,7 +509,7 @@ ...@@ -509,7 +509,7 @@
<virtualType name="AdyenPaymentRefundRequest" type="Magento\Payment\Gateway\Request\BuilderComposite"> <virtualType name="AdyenPaymentRefundRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments> <arguments>
<argument name="builders" xsi:type="array"> <argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item> <!--<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>-->
<item name="refund" xsi:type="string">Adyen\Payment\Gateway\Request\RefundDataBuilder</item> <item name="refund" xsi:type="string">Adyen\Payment\Gateway\Request\RefundDataBuilder</item>
</argument> </argument>
</arguments> </arguments>
...@@ -561,7 +561,7 @@ ...@@ -561,7 +561,7 @@
<arguments> <arguments>
<argument name="handlers" xsi:type="array"> <argument name="handlers" xsi:type="array">
<item name="capture" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentRefundDetailsHandler</item> <item name="capture" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentRefundDetailsHandler</item>
<item name="payment_comments" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentCommentHistoryHandler</item> <item name="payment_comments" xsi:type="string">Adyen\Payment\Gateway\Response\PaymentCommentHistoryRefundHandler</item>
</argument> </argument>
</arguments> </arguments>
</virtualType> </virtualType>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
--> -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Adyen_Payment" setup_version="1.4.5"> <module name="Adyen_Payment" setup_version="1.4.5.1">
<sequence> <sequence>
<module name="Magento_Sales"/> <module name="Magento_Sales"/>
<module name="Magento_Quote"/> <module name="Magento_Quote"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment