Source of file NotificationCompleteService.php
Size: 4,335 Bytes - Last Modified: 2021-12-23T10:34:19+00:00
/var/www/docs.ssmods.com/process/src/src/Service/NotificationCompleteService.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 | <?php namespace SilverStripe\Omnipay\Service; use SilverStripe\Omnipay\Exception\InvalidStateException; use SilverStripe\Omnipay\Exception\InvalidConfigurationException; use SilverStripe\Omnipay\Model\Payment; /** * Abstract base class for payment services that operate on an existing transaction. Examples of this are: * Void, Refund and Capture. * * This service models the following pattern: * * A request is made to the gateway, using an existing transaction ID. * * If the request is successful, the goal state is reached. * * If the payment provider will report success via async notification, the notification is being handled in the `complete` method. * * @package SilverStripe\Omnipay\Service */ abstract class NotificationCompleteService extends PaymentService { /** @var string the start state */ protected $startState; /** @var string the end state to reach */ protected $endState; /** @var string the pending state name */ protected $pendingState; /** @var string message type used to store requests */ protected $requestMessageType; /** @var string message type used to store errors */ protected $errorMessageType; /** * Complete a pending task. * This is only needed for notification, so this method will always assume $isNotification is true! * * @param array $data * @param bool $isNotification * @return ServiceResponse * @throws InvalidConfigurationException * @throws InvalidStateException */ public function complete($data = array(), $isNotification = true) { // The payment is already in the desired endstate if ($this->payment->Status === $this->endState) { return $this->generateServiceResponse(ServiceResponse::SERVICE_NOTIFICATION); } // we're still in the start state, cannot complete here if ($this->payment->Status === $this->startState) { return $this->generateServiceResponse(ServiceResponse::SERVICE_NOTIFICATION | ServiceResponse::SERVICE_ERROR); } if ($this->payment->Status !== $this->pendingState) { throw new InvalidStateException('Cannot modify this payment. Status is not "'. $this->pendingState .'"'); } $serviceResponse = $this->handleNotification(); // exit early if ($serviceResponse->isError()) { $this->notificationFailure($serviceResponse); return $serviceResponse; } // safety check the payment transaction-number against the transaction reference we get from the notification if (!( $serviceResponse->getOmnipayResponse() && $serviceResponse->getOmnipayResponse()->getTransactionReference() == $this->payment->TransactionReference )) { // flag as an error if transaction references don't match $serviceResponse->addFlag(ServiceResponse::SERVICE_ERROR); $this->createMessage($this->errorMessageType, 'Transaction references do not match!'); } // check if we're done if (!$serviceResponse->isError() && !$serviceResponse->isAwaitingNotification()) { $this->markCompleted($this->endState, $serviceResponse, $serviceResponse->getOmnipayResponse()); } return $serviceResponse; } /** * Method to handle notification failures. Here we have to check if the gateway actually reported a failure * and then update the payment status accordingly! * @param ServiceResponse $serviceResponse * @return void */ protected function notificationFailure($serviceResponse) { $omnipayResponse = $serviceResponse->getOmnipayResponse(); // if there's no response from the gateway, don't bother. Errors are already in messages/log if (!$omnipayResponse) { return; } // void any pending partial payments $pending = $this->payment->getPartialPayments()->filter('Status', $this->pendingState); /** @var Payment $payment */ foreach ($pending as $payment) { $payment->Status = 'Void'; $payment->write(); } // reset the payment to the start-state $this->payment->Status = $this->startState; $this->payment->write(); } } |