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); }