/** * Get message * * @return string */ public function getMessage() { $message = \XLite\Model\Payment\Transaction::getDefaultFailedReason(); if (\XLite\Core\Request::getInstance()->message) { $message = urldecode(\XLite\Core\Request::getInstance()->message); } return $message; }
public function processCallback(\XLite\Model\Payment\Transaction $transaction) { $post = file_get_contents("php://input"); if (true === empty($post)) { return array('error' => 'No post data'); error_log("No post data"); } $json = json_decode($post, true); if (true === is_string($json)) { return array('error' => $json); error_log($json); } if (false === array_key_exists('posData', $json)) { return array('error' => 'no posData'); error_log("no posData"); } if (false === array_key_exists('id', $json)) { return 'Cannot find invoice ID'; error_log("Cannot find invoice ID"); } $method = \XLite\Core\Database::getRepo('\\XLite\\Model\\Payment\\Method')->createQueryBuilder('p')->where('p.service_name = \'BitPay\'')->getResult()[0]; $bitpayWrapper = new XcartWrapper($method); $response = $bitpayWrapper->getInvoice($json['id']); $invoiceId = $response->getPosData(); switch ($response->getStatus()) { case 'paid': error_log("Paid for Invoice ID: " . $invoiceId); error_log("The payment has been received, but the transaction has not been confirmed on the bitcoin network. This will be updated when the transaction has been confirmed."); $status = $transaction::STATUS_PENDING; break; case 'confirmed': error_log("Confirmed for Invoice ID: " . $invoiceId); error_log("The payment has been received, and the transaction has been confirmed on the bitcoin network. This will be updated when the transaction has been completed."); $status = $transaction::STATUS_PENDING; break; case 'complete': error_log("Complete for Invoice ID: " . $invoiceId); error_log("The transaction is now complete."); $status = $transaction::STATUS_SUCCESS; break; } $transaction->setStatus($status); }
/** * Returns default fa * * @return string */ protected function getDefaultFailureReason() { return \XLite\Model\Payment\Transaction::getDefaultFailedReason(); }
/** * Get default options * * @return array */ protected function getDefaultOptions() { return array('' => 'All payment transaction statuses') + \XLite\Model\Payment\Transaction::getStatuses(); }
/** * Register backend transaction * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction object * @param string $transactionType Type of backend transaction * * @return \XLite\Model\Payment\BackendTransaction */ protected function registerBackendTransaction(\XLite\Model\Payment\Transaction $transaction, $transactionType) { $backendTransaction = $transaction->createBackendTransaction($transactionType); $transactionData = $this->getRequestData(); $transactionData[] = array('name' => 'PPREF', 'value' => \XLite\Core\Request::getInstance()->txn_id, 'label' => 'Unique PayPal transaction ID (PPREF)'); foreach ($transactionData as $data) { $backendTransaction->setDataCell($data['name'], $data['value'], $data['label']); } return $backendTransaction; }
/** * Check if transaction is X-Payments's one and is initialized/in progress * * @param \XLite\Model\Payment\Transaction $transaction Transaction * * @return void */ protected function isTransactionOpenXpayments(\XLite\Model\Payment\Transaction $transaction) { return $transaction && $transaction->isXpc() && $transaction->isOpen(); }
/** * Get specific transaction URL on PayPal side * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction object * @param string $id Transaction ID (PPREF) * * @return string */ protected function getTransactionIdURL($transaction, $id) { $isTestMode = $transaction->getDataCell('test_mode'); return isset($isTestMode) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=' . $id : 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=' . $id; }
/** * Do Recharge the difference 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\Order $order Order which is recharged * @param \XLite\Model\Payment\Transaction $parentCardTransaction Trandaction with saved card * @param float $amount Amount to recharge * * @return boolean */ public function doRecharge(\XLite\Model\Order $order, \XLite\Model\Payment\Transaction $parentCardTransaction, $amount) { $newTransaction = new \XLite\Model\Payment\Transaction(); $newTransaction->setPaymentMethod($this->getSavedCardsPaymentMethod()); $newTransaction->setStatus(\XLite\Model\Payment\Transaction::STATUS_INPROGRESS); $newTransaction->setDataCell('is_recharge', 'Y', null, 'C'); $newTransaction->setValue($amount); $order->addPaymentTransactions($newTransaction); $newTransaction->setOrder($order); foreach ($this->paymentSettingsToSave as $field) { $key = 'xpc_can_do_' . $field; if ($parentCardTransaction->getDataCell($key) && $parentCardTransaction->getDataCell($key)->getValue()) { $newTransaction->setDataCell($key, $parentCardTransaction->getDataCell($key)->getValue(), null, 'C'); } } $this->copyMaskedCard($parentCardTransaction, $newTransaction); $recharge = $this->client->requestPaymentRecharge($parentCardTransaction->getDataCell('xpc_txnid')->getValue(), $newTransaction); if ($recharge->isSuccess()) { $response = $recharge->getResponse(); if (self::STATUS_AUTH == $response['status'] || self::STATUS_CHARGED == $response['status']) { \XLite\Core\TopMessage::getInstance()->addInfo($response['message'] ? $response['message'] : 'Operation successfull'); if ($response['transaction_id']) { $newTransaction->setDataCell('xpc_txnid', $response['transaction_id'], 'X-Payments transaction ID', 'C'); } } else { \XLite\Core\TopMessage::getInstance()->addError($response['error'] ? $response['error'] : 'Operation failed'); $newTransaction->setStatus(\XLite\Model\Payment\Transaction::STATUS_FAILED); } } else { $message = 'Operation failed'; if ($recharge->getError()) { $message .= '. ' . $recharge->getError(); } \XLite\Core\TopMessage::getInstance()->addError($message); $newTransaction->setStatus(\XLite\Model\Payment\Transaction::STATUS_FAILED); } \XLite\Core\Database::getEM()->flush(); }
/** * Add top message about transaction results * * @return void */ protected function assignTransactionMessage() { $txnNote = \XLite\Core\Request::getInstance()->txnNote ? base64_decode(\XLite\Core\Request::getInstance()->txnNote) : null; $txnNoteType = \XLite\Core\Request::getInstance()->txnNoteType; if ($txnNote) { $message = strip_tags($txnNote); if (\XLite\Core\TopMessage::ERROR == $txnNoteType) { if (\XLite\Model\Payment\Transaction::getDefaultFailedReason() == $txnNote) { // Display default message \XLite\Core\TopMessage::addError($message); } else { // Display specific transaction message \XLite\Core\TopMessage::addError($this->getCommonErrorMessage(), array('txnNote' => $message)); } } else { // Display transaction success message \XLite\Core\TopMessage::addInfo($message); } } }
/** * Convert order to array for DoExpressCheckoutPayment * * @param \XLite\Model\Payment\Transaction $transaction Transaction * @param string $token Token * @param string $payerId Payer id * * @return array * @see https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/ */ public function convertDoExpressCheckoutPaymentParams($transaction, $token, $payerId) { /** @var \XLite\Model\Order $order */ $order = $transaction->getOrder(); /** @var \XLite\Model\Currency $currency */ $currency = $order->getCurrency(); $orderTotal = $currency->roundValue($transaction->getValue()); $shippingCost = $this->getShippingCost($order); /** @var \XLite\Module\CDev\Paypal\Model\Payment\Processor\ExpressCheckoutMerchantAPI $processor */ $processor = $this->getProcessor(); $params = array('TOKEN' => $token, 'PAYERID' => $payerId, 'PAYMENTREQUEST_0_AMT' => $orderTotal, 'PAYMENTREQUEST_0_PAYMENTACTION' => $this->getPaymentAction(), 'PAYMENTREQUEST_0_CURRENCYCODE' => $currency->getCode(), 'PAYMENTREQUEST_0_HANDLINGAMT' => 0, 'PAYMENTREQUEST_0_INSURANCEAMT' => 0, 'PAYMENTREQUEST_0_SHIPPINGAMT' => (double) $shippingCost, 'PAYMENTREQUEST_0_NOTIFYURL' => $processor->getPaymentCallbackUrl()); $items = $this->getItems($order); // To avoid total mismatch clear tax and shipping cost $taxAmt = isset($items['PAYMENTREQUEST_0_TAXAMT']) ? $items['PAYMENTREQUEST_0_TAXAMT'] : 0; if (abs($orderTotal - $items['PAYMENTREQUEST_0_ITEMAMT'] - $taxAmt - $shippingCost) > 1.0E-10) { $correction = $orderTotal - $items['PAYMENTREQUEST_0_ITEMAMT'] - $taxAmt - $shippingCost; $correction = round($correction, 2); $index = $order->countItems() + 1; $items['L_PAYMENTREQUEST_0_AMT' . $index] = $correction; $items['L_PAYMENTREQUEST_0_NAME' . $index] = 'Correction'; $items['L_PAYMENTREQUEST_0_QTI' . $index] = 1; $items['PAYMENTREQUEST_0_ITEMAMT'] += $correction; } $params += $items; return $params; }
/** * Preprocess value * * @param float $value Status code * @param array $column Column info * @param \XLite\Model\Payment\Transaction $entity Payment transaction * * @return string */ protected function preprocessValue($value, array $column, \XLite\Model\Payment\Transaction $entity) { return static::formatPrice($value, $entity->getCurrency()); }
/** * Convert order to array for DoExpressCheckoutPayment * * @param \XLite\Model\Payment\Transaction $transaction Transaction * @param string $token Token * @param string $payerId Payer id * * @return array * @see https://www.paypalobjects.com/webstatic/en_US/developer/docs/pdf/pfp_expresscheckout_pp.pdf */ public function convertDoExpressCheckoutPaymentParams($transaction, $token, $payerId) { /** @var \XLite\Model\Order $order */ $order = $transaction->getOrder(); /** @var \XLite\Model\Currency $currency */ $currency = $order->getCurrency(); $orderTotal = $currency->roundValue($transaction->getValue()); $shippingCost = $this->getShippingCost($order); /** @var \XLite\Module\CDev\Paypal\Model\Payment\Processor\ExpressCheckoutMerchantAPI $processor */ $processor = $this->getProcessor(); $params = array('TRXTYPE' => $this->getPaymentAction(), 'TENDER' => 'P', 'ACTION' => 'D', 'TOKEN' => $token, 'PAYERID' => $payerId, 'AMT' => $orderTotal, 'CURRENCY' => $currency->getCode(), 'FREIGHTAMT' => (double) $shippingCost, 'HANDLINGAMT' => 0, 'INSURANCEAMT' => 0, 'NOTIFYURL' => $processor->getPaymentCallbackUrl(), 'ALLOWNOTE' => 1); $items = $this->getItems($order); // To avoid total mismatch clear tax and shipping cost $taxAmt = isset($items['TAXAMT']) ? $items['TAXAMT'] : 0; if (abs($orderTotal - $items['ITEMAMT'] - $taxAmt - $shippingCost) > 1.0E-10) { $items['ITEMAMT'] = $orderTotal; $items['TAXAMT'] = 0; $params['FREIGHTAMT'] = 0; } $params += $items; return $params; }
/** * Check payment transaction status * * @param \XLite\Model\Payment\Transaction $transaction Transaction * @param string $status Status * * @return void */ public function checkPaymentTransactionStatusEqual(\XLite\Model\Payment\Transaction $transaction, $status) { return $transaction->getStatus() == $status; }
/** * Get charge value modifier * * @return float */ public function getChargeValueModifier() { if ($this->isXpc(true)) { list($authorized, $paid, $voided, $refunded) = $this->getXpcValues(); $positive = max($authorized, $paid); $negative = $voided + $refunded; $value = $positive - $negative; } else { $value = parent::getChargeValueModifier(); } return $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; }
/** * Get list of allowed backend transactions * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction * * @return array */ protected function getTransactionUnits($transaction = null) { if (!isset($this->allowedTransactions) && isset($transaction)) { $processor = $transaction->getPaymentMethod()->getProcessor(); $this->allowedTransactions = $processor->getAllowedTransactions(); foreach ($this->allowedTransactions as $k => $v) { if (!$processor->isTransactionAllowed($transaction, $v) || !$this->isTransactionFiltered($v)) { unset($this->allowedTransactions[$k]); } } } return $this->allowedTransactions; }
/** * Get transaction additional data * * @param \XLite\Model\Payment\Transaction $transaction Transaction * * @return array */ protected function getTransactionData(\XLite\Model\Payment\Transaction $transaction) { $list = array(); foreach ($transaction->getData() as $cell) { if ($cell->getLabel()) { $list[] = $cell; } } return $list; }
/** * Get setting value by name * * @param string $name Name * * @return mixed */ protected function getSetting($name) { return $this->transaction ? $this->transaction->getPaymentMethod()->getSetting($name) : null; }
/** * Check - payment method is editable or not * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction * * @return boolean */ protected function isPaymentMethodEditable(\XLite\Model\Payment\Transaction $transaction) { return $this->isOrderEditable() && $transaction->getPaymentMethod() && $transaction->getPaymentMethod()->getType() === \XLite\Model\Payment\Method::TYPE_OFFLINE; }
/** * Get init payment form data from XPayments * * @param \XLite\Model\Payment\Transaction $transaction Transaction * * @return array */ protected function getInitDataFromXpayments(\XLite\Model\Payment\Transaction $transaction) { $init = $this->requestPaymentInit($transaction->getPaymentMethod(), \XLite\Model\Cart::getInstance()); if ($init->isSuccess()) { $response = $init->getResponse(); $data = array('xpcBackReference' => $response['xpcBackReference'], 'txnId' => $response['txnId'], 'fields' => $response['fields']); $this->saveInitDataToSession($transaction, $data); } else { $data = null; $this->setXpcInitError($transaction, $init->getError()); } return $data; }
/** * Set order status by transaction * * @param \XLite\Model\Payment\Transaction $transaction Transaction which changes status * * @return void */ public function setPaymentStatusByTransaction(\XLite\Model\Payment\Transaction $transaction) { if ($this->isPayed()) { $status = $transaction->isCaptured() ? \XLite\Model\Order\Status\Payment::STATUS_PAID : \XLite\Model\Order\Status\Payment::STATUS_AUTHORIZED; } else { if ($transaction->isRefunded()) { $paymentTransactionSums = $this->getRawPaymentTransactionSums(); $refunded = $paymentTransactionSums['refunded']; // Check if the whole refunded sum (along with the previous refunded transactions for the order) // covers the whole total for order $status = $refunded < (double) $this->getTotal() ? \XLite\Model\Order\Status\Payment::STATUS_PAID : \XLite\Model\Order\Status\Payment::STATUS_REFUNDED; } elseif ($transaction->isFailed()) { $status = \XLite\Model\Order\Status\Payment::STATUS_DECLINED; } elseif ($transaction->isVoid()) { $status = \XLite\Model\Order\Status\Payment::STATUS_DECLINED; } elseif ($transaction->isCaptured()) { $status = \XLite\Model\Order\Status\Payment::STATUS_PART_PAID; } else { $status = \XLite\Model\Order\Status\Payment::STATUS_QUEUED; } } $this->setPaymentStatus($status); }
/** * Send request to X-Payments to initialize new payment * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction * @param \XLite\Model\Cart $cart Shopping cart info * @param boolean $forceAuth Force enable AUTH mode OPTIONAL * * @return array */ protected function requestPaymentInit(\XLite\Model\Payment\Transaction $transaction, \XLite\Model\Cart $cart, $forceAuth = false) { $paymentMethod = $transaction->getPaymentMethod(); // Prepare cart $preparedCart = $this->prepareCart($cart, $paymentMethod, null, $forceAuth); if ($cart && $preparedCart) { $xpcBackReference = $transaction->getPublicId(); // Send request to X-Payments $result = $this->apiRequest->send('payment', 'init', $this->getInitRequestData($paymentMethod->getSetting('id'), $xpcBackReference, $preparedCart)); if ($result->isSuccess()) { $response = $result->getResponse(); // Set fields for the "Redirect to X-Payments" form $result->setResponse(array('xpcBackReference' => $xpcBackReference, 'txnId' => $response['txnId'], 'module_name' => $paymentMethod->getSetting('moduleName'), 'url' => \XLite\Core\Config::getInstance()->CDev->XPaymentsConnector->xpc_xpayments_url . '/payment.php', 'fields' => array('target' => 'main', 'action' => 'start', 'token' => $response['token']))); } } else { // Something is wrong with the cart. Should not ever happen $result = new \XLite\Module\CDev\XPaymentsConnector\Transport\Response(); $result->setError('Unable to prepare cart data'); } return $result; }
/** * Update status of backend transaction related to an initial payment transaction * * @param \XLite\Model\Payment\Transaction $transaction Payment transaction * @param string $status Transaction status * * @return void */ public function updateInitialBackendTransaction(\XLite\Model\Payment\Transaction $transaction, $status) { $backendTransaction = $transaction->getInitialBackendTransaction(); if (isset($backendTransaction)) { $backendTransaction->setStatus($status); $this->saveDataFromRequest($backendTransaction); } }
/** * {@inheritDoc} */ public function prepareEntityBeforeCommit($type) { $this->__initializer__ && $this->__initializer__->__invoke($this, 'prepareEntityBeforeCommit', array($type)); return parent::prepareEntityBeforeCommit($type); }
/** * Save some payment settings from payment method to the transaction * * @param \XLite\Model\Payment\Transaction $transaction Transaction * * @return string */ public function savePaymentSettingsToTransaction(\XLite\Model\Payment\Transaction $transaction, $parentTransaction = null) { if ($parentTransaction) { $paymentMethod = $parentTransaction->getPaymentMethod(); } else { $paymentMethod = $transaction->getPaymentMethod(); } foreach ($this->paymentSettingsToSave as $field) { $key = 'xpc_can_do_' . $field; if ($paymentMethod->getSetting($field)) { $transaction->setDataCell($key, $paymentMethod->getSetting($field), null, 'C'); } } $transaction->setDataCell('xpc_session_id', \XLite\Core\Session::getInstance()->getID(), null, 'C'); }
/** * Set note * * @param string $note * * @return Transaction */ public function setNote($note) { if (strlen($note) > self::NOTE_LIMIT) { // truncate note for STRICT_TRANS_TABLES $note = function_exists('mb_substr') ? mb_substr($value, 0, self::NOTE_LIMIT - 3) : substr($value, 0, self::NOTE_LIMIT - 3); $note .= '...'; } return parent::setNote($note); }