protected function markCompleted($endStatus, ServiceResponse $serviceResponse, $gatewayMessage)
 {
     // Get partial payments
     $partials = $this->payment->getPartialPayments()->filter('Status', $this->pendingState);
     if ($partials->count() > 0) {
         $i = 0;
         $total = $this->payment->MoneyAmount;
         foreach ($partials as $payment) {
             // only the first, eg. most recent payment should be considered valid. All others should be set to void
             if ($i === 0) {
                 $total = PaymentMath::add($total, $payment->MoneyAmount);
                 $payment->Status = 'Created';
                 $payment->setAmount(PaymentMath::multiply($payment->MoneyAmount, '-1'));
                 $payment->Status = 'Refunded';
             } else {
                 $payment->Status = 'Void';
             }
             $payment->write();
             $i++;
         }
         // Ugly hack to set the money amount
         $this->payment->Status = 'Created';
         $this->payment->setAmount($total);
         // If not everything was refunded, the payment should still have the "Captured" status
         if ($total > 0) {
             $endStatus = 'Captured';
         }
     }
     parent::markCompleted($endStatus, $serviceResponse, $gatewayMessage);
     if ($endStatus === 'Captured') {
         $this->createMessage('PartiallyRefundedResponse', $gatewayMessage);
     } else {
         $this->createMessage('RefundedResponse', $gatewayMessage);
     }
     Helper::safeExtend($this->payment, 'onRefunded', $serviceResponse);
 }
 protected function markCompleted($endStatus, ServiceResponse $serviceResponse, $gatewayMessage)
 {
     // Get partial payments
     $partials = $this->payment->getPartialPayments()->filter('Status', $this->pendingState);
     if ($partials->count() > 0) {
         $i = 0;
         $total = $originalTotal = $this->payment->MoneyAmount;
         foreach ($partials as $payment) {
             // only the first, eg. most recent payment should be considered valid. All others should be set to void
             if ($i === 0) {
                 $total = PaymentMath::add($total, $payment->MoneyAmount);
                 // deal with partial capture
                 if ($payment->MoneyAmount < 0) {
                     $payment->Status = 'Created';
                     $payment->setAmount(PaymentMath::multiply($payment->MoneyAmount, '-1'));
                     $payment->Status = 'Captured';
                 } else {
                     // void excess amounts
                     $payment->Status = 'Void';
                 }
             } else {
                 $payment->Status = 'Void';
             }
             $payment->write();
             $i++;
         }
         // Ugly hack to set the money amount
         $this->payment->Status = 'Created';
         $this->payment->setAmount($total);
         // If not everything was captured (partial),
         // the payment should be refunded or still Authorized (in case multiple captures are possible)
         if ($total > 0 && $total < $originalTotal) {
             $endStatus = GatewayInfo::captureMode($this->payment->Gateway) === GatewayInfo::MULTIPLE ? 'Authorized' : 'Refunded';
         }
     }
     parent::markCompleted($endStatus, $serviceResponse, $gatewayMessage);
     if ($endStatus === 'Captured') {
         $this->createMessage('CapturedResponse', $gatewayMessage);
     } else {
         $this->createMessage('PartiallyCapturedResponse', $gatewayMessage);
     }
     Helper::safeExtend($this->payment, 'onCaptured', $serviceResponse);
 }
 /**
  * Calculate the max amount that can be captured for this payment.
  * If the Status of the payment isn't 'Authorized', this will return 0
  * @return int|string the max amount that can be captured for this payment.
  */
 public function getMaxCaptureAmount()
 {
     if ($this->Status !== 'Authorized') {
         return 0;
     }
     $percent = GatewayInfo::maxExcessCapturePercent($this->Gateway);
     $fixedAmount = GatewayInfo::maxExcessCaptureAmount($this->Gateway, $this->getCurrency());
     // -1 will only be returned if there's a fixed amount, but no percentage.
     // We can safely return the fixed amount here
     if ($percent === -1) {
         return PaymentMath::add($this->MoneyAmount, $fixedAmount);
     }
     // calculate what amount the percentage will result in
     $percentAmount = PaymentMath::multiply(PaymentMath::multiply($percent, '0.01'), $this->MoneyAmount);
     // if there's no fixed amount and only the percentage is set, we can return the percentage amount right away.
     if ($fixedAmount === -1) {
         return PaymentMath::add($this->MoneyAmount, $percentAmount);
     }
     // If the amount from the percentage is smaller, use the percentage
     if (PaymentMath::compare($fixedAmount, $percentAmount) > 0) {
         return PaymentMath::add($this->MoneyAmount, $percentAmount);
     }
     // otherwise use the fixed amount
     return PaymentMath::add($this->MoneyAmount, $fixedAmount);
 }