/** * Get reference ID of parent transaction * (e.g. get PNREF of AUTH transaction for request a CAPTURE transaction) * * @param \XLite\Model\Payment\BackendTransaction $backendTransaction Backend transaction object * * @return string */ protected function getTransactionReferenceId(\XLite\Model\Payment\BackendTransaction $backendTransaction) { $referenceId = null; $paymentTransaction = $backendTransaction->getPaymentTransaction(); switch ($backendTransaction->getType()) { case \XLite\Model\Payment\BackendTransaction::TRAN_TYPE_CAPTURE: case \XLite\Model\Payment\BackendTransaction::TRAN_TYPE_VOID: if (\XLite\Model\Payment\BackendTransaction::TRAN_TYPE_AUTH == $paymentTransaction->getType()) { $referenceId = $paymentTransaction->getDataCell($this->getReferenceIdField())->getValue(); } break; case \XLite\Model\Payment\BackendTransaction::TRAN_TYPE_REFUND: if (\XLite\Model\Payment\BackendTransaction::TRAN_TYPE_SALE == $paymentTransaction->getType()) { $referenceId = $paymentTransaction->getDataCell($this->getReferenceIdField())->getValue(); } elseif ($paymentTransaction->isCaptured()) { foreach ($paymentTransaction->getBackendTransactions() as $bt) { if (\XLite\Model\Payment\BackendTransaction::TRAN_TYPE_CAPTURE == $bt->getType() && \XLite\Model\Payment\Transaction::STATUS_SUCCESS == $bt->getStatus()) { $referenceId = $bt->getDataCell($this->getReferenceIdField())->getValue(); break; } } } break; default: break; } return $referenceId; }
/** * Refund * * @param \XLite\Model\Payment\BackendTransaction $transaction Backend transaction * * @return boolean */ protected function doRefund(\XLite\Model\Payment\BackendTransaction $transaction) { $this->includeVelocityLibrary(); $backendTransactionStatus = $transaction::STATUS_FAILED; $errorData = ''; if ($this->getSetting('mode') == 'test') { $isTestAccount = true; } else { $isTestAccount = false; } try { $velocityProcessor = new \VelocityProcessor(self::$applicationprofileid, self::$merchantprofileid, self::$workflowid, $isTestAccount, self::$identitytoken); } catch (Exception $e) { $transaction->setDataCell('error_message', $e->getMessage(), 'Velocity error message'); $errorData .= $e->getMessage(); } $refund_amount = $transaction->getValue(); $txnid = $transaction->getPaymentTransaction()->getDataCell('velocity_payment_id')->getValue(); try { // request for refund $response = $velocityProcessor->returnById(array('amount' => $refund_amount, 'TransactionId' => $txnid)); $xml = \VelocityXmlCreator::returnByIdXML($refund_amount, $txnid); // got ReturnById xml object. $req = $xml->saveXML(); $obj_req = serialize($req); if (is_array($response) && !empty($response) && isset($response['Status']) && $response['Status'] == 'Successful') { $backendTransactionStatus = $transaction::STATUS_SUCCESS; $transaction->setDataCell('velocity_refund_id', $response['TransactionId'], 'Velocity Refund ID'); $transaction->setDataCell('approval_code', $response['ApprovalCode'], 'Velocity Approval Code'); $transaction->setDataCell('request_refund_object', $obj_req, 'Velocity Request Refund Object'); $transaction->setDataCell('response_refund_object', serialize($response), 'Velocity Response Refund Object'); $transaction->setDataCell('refund_status', $response['TransactionState'], 'Refund Transaction Status'); $transaction->setStatus($backendTransactionStatus); \XLite\Core\Database::getEM()->flush(); } else { if (is_array($response) && !empty($response)) { $transaction->setDataCell('error_message', $response['StatusMessage'], 'Velocity error message'); $errorData .= $response['StatusMessage']; } else { if (is_string($response)) { $transaction->setDataCell('error_message', $response, 'Velocity error message'); $errorData .= $response; } else { $transaction->setDataCell('error_message', 'Unknown Error please contact the site admin', 'Velocity error message'); $errorData .= 'Unknown Error please contact the site admin'; } } } } catch (Exception $e) { $transaction->setDataCell('error_message', $e->getMessage(), 'Velocity error message'); $errorData .= $e->getMessage(); } if (\XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS == $backendTransactionStatus) { $order = $transaction->getPaymentTransaction()->getOrder(); $paymentTransactionSums = $order->getRawPaymentTransactionSums(); $refunded = $paymentTransactionSums['refunded']; $status = $refunded < $transaction->getPaymentTransaction()->getValue() ? \XLite\Model\Order\Status\Payment::STATUS_PART_PAID : \XLite\Model\Order\Status\Payment::STATUS_REFUNDED; $order->setPaymentStatus($status); \XLite\Core\TopMessage::getInstance()->addInfo('Payment has been refunded successfully'); } else { $msg = 'Transaction failure'; if (!empty($errorData)) { $msg .= '-' . $errorData; } \XLite\Core\TopMessage::getInstance()->addError($msg); } return \XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS == $backendTransactionStatus; }
/** * Process DoCapture response * * @param \XLite\Model\Payment\BackendTransaction $transaction Transaction * @param string $responseData Response data OPTIONAL * * @return boolean */ protected function processRefundTransactionResponse(\XLite\Model\Payment\BackendTransaction $transaction, $responseData = null) { $result = false; if (!empty($responseData)) { $status = \XLite\Model\Payment\Transaction::STATUS_FAILED; if ('Success' === $responseData['ACK']) { $result = true; $status = \XLite\Model\Payment\Transaction::STATUS_SUCCESS; $transaction->getPaymentTransaction()->getOrder()->setPaymentStatus(\XLite\Model\Order\Status\Payment::STATUS_REFUNDED); // save transaction id for IPN $transaction->setDataCell('PPREF', $responseData['REFUNDTRANSACTIONID'], 'Unique PayPal transaction ID (REFUNDTRANSACTIONID)'); \XLite\Core\TopMessage::getInstance()->addInfo('Payment has bes refunded successfully'); } else { \XLite\Core\TopMessage::getInstance()->addError('Transaction failure. PayPal response: ' . $responseData['L_LONGMESSAGE0']); } $transaction->setStatus($status); $transaction->update(); } return $result; }
protected function doRefund(\XLite\Model\Payment\BackendTransaction $transaction, $isDoVoid = false) { $this->includeSecuresubmitLibrary(); $backendTransactionStatus = \XLite\Model\Payment\BackendTransaction::STATUS_FAILED; $transactionId = $transaction->getPaymentTransaction()->getDataCell('heartland_id')->getValue(); try { if ($isDoVoid) { $payment = $this->chargeService->void($transactionId); } else { $payment = $this->chargeService->refund($this->transaction->getValue(), 'usd', $transactionId); } $backendTransactionStatus = \XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS; $transaction->setDataCell('refund_txnid', $payment->transactionId); } catch (\Exception $e) { $transaction->setDataCell('errorMessage', $e->getMessage()); \XLite\Logger::getInstance()->log($e->getMessage(), LOG_ERR); \XLite\Core\TopMessage::addError($e->getMessage()); } $transaction->setStatus($backendTransactionStatus); return \XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS == $backendTransactionStatus; }
/** * Do Capture, Void or Refund request. * Returns false on failure or redirects admin back to the order page * the necessary actions with the backend transaction are taken in the * Callback request processing * * @param \XLite\Model\Payment\BackendTransaction $transaction Trandaction * @param string $paymentAction Payment action * * @return boolean */ protected function doSecondary(\XLite\Model\Payment\BackendTransaction $transaction, $paymentAction) { if (!array_key_exists($paymentAction, $this->secondaryActionsMap)) { return false; } if (\XLite\Core\Request::getInstance()->trn_id) { $pt = \XLite\Core\Database::getRepo('XLite\\Model\\Payment\\Transaction')->find(\XLite\Core\Request::getInstance()->trn_id); } else { $pt = $transaction->getPaymentTransaction(); } $method = $this->secondaryActionsMap[$paymentAction]['method']; $action = $this->secondaryActionsMap[$paymentAction]['action']; $result = $this->client->{$method}($pt->getDataCell('xpc_txnid')->getValue(), $pt, \XLite\Core\Request::getInstance()->amount); if ($result->isSuccess()) { $response = $result->getResponse(); if ('1' == $response['status']) { \XLite\Core\TopMessage::getInstance()->addInfo($response['message'] ? 'Transaction was ' . $action . ' with message: ' . $response['message'] : 'Operation successfull'); $controller = \XLite::getController()->redirectBackToOrder(); exit; } else { if ($response['error']) { $message = 'Transaction was not ' . $action . 'with error: ' . $response['error']; } elseif ($response['message']) { $message = 'Transaction was not ' . $action . 'with message: ' . $response['message']; } else { $mesage = 'Operation failed'; } \XLite\Core\TopMessage::getInstance()->addError($message); } } else { $message = 'Operation failed'; if ($result->getError()) { $messsage .= '. ' . $result->getError(); } \XLite\Core\TopMessage::getInstance()->addError($message); } return false; }
/** * Convert order to array for RefundTransaction * * @param \XLite\Model\Payment\BackendTransaction $transaction Transaction * @param string $transactionId Transaction id * * @return array * @see https://developer.paypal.com/docs/classic/api/merchant/DoVoid_API_Operation_NVP/ */ public function convertRefundTransactionParams($transaction, $transactionId) { /** @var \XLite\Model\Order $order */ $order = $transaction->getPaymentTransaction()->getOrder(); /** @var \XLite\Model\Currency $currency */ $currency = $order->getCurrency(); $amount = $currency->roundValue($transaction->getValue()); return array('TRANSACTIONID' => $transactionId, 'AMT' => $amount); }
/** * Preprocess type * * @param string $value Status code * @param array $column Column info * @param \XLite\Model\Payment\Transaction $entity Payment transaction * * @return string */ protected function preprocessType($value, array $column, \XLite\Model\Payment\Transaction $entity) { $list = \XLite\Model\Payment\BackendTransaction::getTypes(); return static::t($list[$value]); }
/** * Retrieve property from the model object * * @param mixed $name Field/property name * * @return mixed */ protected function getModelObjectValue($name) { $result = parent::getModelObjectValue($name); switch ($name) { case 'date': $result = $this->formatTime($result); break; case 'method_name': $result = $this->getModelObject()->getPaymentMethod() ? $this->getModelObject()->getPaymentMethod()->getName() : $result; break; case 'type': $list = \XLite\Model\Payment\BackendTransaction::getTypes(); $result = $list[$result]; break; case 'status': $list = \XLite\Model\Payment\Transaction::getStatuses(); $result = $list[$result]; break; case 'value': $result = static::formatPrice($result, $this->getModelObject()->getCurrency()); break; case 'note': if (!$result) { $result = static::t('n/a'); } break; default: } return $result; }
/** * Refund * * @param \XLite\Model\Payment\BackendTransaction $transaction Backend transaction * @param boolean $isDoVoid Is void action OPTIONAL * * @return boolean */ protected function doRefund(\XLite\Model\Payment\BackendTransaction $transaction, $isDoVoid = false) { $this->includeStripeLibrary(); $backendTransactionStatus = \XLite\Model\Payment\BackendTransaction::STATUS_FAILED; try { $payment = \Stripe_Charge::retrieve($transaction->getPaymentTransaction()->getDataCell('stripe_id')->getValue()); if ($transaction->getValue() != $transaction->getPaymentTransaction()->getValue()) { $payment->refund(array('id' => $transaction->getPaymentTransaction()->getDataCell('stripe_id')->getValue(), 'amount' => $this->formatCurrency($transaction->getValue()))); $refundTransaction = null; foreach ($payment->refunds as $r) { if (!$this->isRefundTransactionRegistered($r)) { $refundTransaction = $r; break; } } } else { $payment->refund(); $refundTransaction = reset($payment->refunds); } if ($refundTransaction) { $backendTransactionStatus = \XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS; $transaction->setDataCell('stripe_date', $refundTransaction->created); if ($refundTransaction->balance_transaction) { $transaction->setDataCell('stripe_b_txntid', $refundTransaction->balance_transaction); } } } catch (\Exception $e) { $transaction->setDataCell('errorMessage', $e->getMessage()); \XLite\Logger::getInstance()->log($e->getMessage(), LOG_ERR); \XLite\Core\TopMessage::addError($e->getMessage()); } $transaction->setStatus($backendTransactionStatus); return \XLite\Model\Payment\BackendTransaction::STATUS_SUCCESS == $backendTransactionStatus; }
/** * {@inheritDoc} */ public function prepareEntityBeforeCommit($type) { $this->__initializer__ && $this->__initializer__->__invoke($this, 'prepareEntityBeforeCommit', array($type)); return parent::prepareEntityBeforeCommit($type); }