/**
  * @param PaymentInterface $payment
  * @throws InvalidPaymentException
  */
 public function check(PaymentInterface $payment)
 {
     if ($payment->getTransaction()) {
         throw new InvalidPaymentException('Payment has already been received.');
     }
     $credentials = new OAuthTokenCredential($this->options['client_id'], $this->options['secret']);
     $apiContext = new ApiContext($credentials);
     $apiContext->setConfig(['mode' => $this->options['mode']]);
     $paypalPayment = Payment::get($payment->getExtraData('paypal_payment_id'), $apiContext);
     $payer = $paypalPayment->getPayer();
     if (!$payer || 'verified' !== strtolower($payer->getStatus())) {
         throw new InvalidPaymentException('Payer not verified.');
     }
     if ('created' == $paypalPayment->getState()) {
         $execution = new PaymentExecution();
         $execution->setPayerId($paypalPayment->getPayer()->getPayerInfo()->getPayerId());
         $paypalPayment->execute($execution, $apiContext);
     }
     if ('approved' != $paypalPayment->getState()) {
         throw new InvalidPaymentException('Invalid payment state.');
     }
     $math = new NativeMath();
     $controlSum = 0;
     foreach ($paypalPayment->getTransactions() as $transaction) {
         if ($transaction->getAmount()->getCurrency() != $payment->getAccount()->getCurrency()) {
             throw new InvalidPaymentException('Invalid payment currency.');
         }
         $controlSum = $math->sum($controlSum, $transaction->getAmount()->getTotal());
     }
     if (!$math->eq($payment->getPaymentSum(), $controlSum)) {
         throw new InvalidPaymentException('Invalid payment sum.');
     }
 }
 /**
  * @param PaymentInterface $payment
  * @return HandlerInterface
  * @throws InvalidPaymentException
  */
 public function getPaymentHandler(PaymentInterface $payment)
 {
     $slug = $payment->getPaymentMethod()->getSlug();
     if (!array_key_exists($slug, $this->handlers)) {
         throw new InvalidPaymentException('Undefined payment method.');
     }
     return $this->handlers[$slug];
 }
 /**
  * @param PaymentInterface $payment
  * @throws InvalidPaymentException
  */
 protected function validatePayment(PaymentInterface $payment)
 {
     /** @var MathInterface $math */
     $math = $this->options['math'];
     $min = $this->options['min_sum'];
     if ($math->lessThan($payment->getPaymentSum(), $min)) {
         throw new InvalidPaymentException(sprintf('Minimal payment sum is %s%s', $min, $this->options['currency']));
     }
 }