'UK', 'de' => 'DE', ); function __construct(& $subject, $config) { //if (self::$_this) // return self::$_this; parent::__construct($subject, $config); $this->_loggable = TRUE; $this->tableFields = array_keys($this->getTableSQLFields()); $this->_tablepkey = 'id'; $this->_tableId = 'id'; $varsToPush = $this->getVarsToPush(); $this->setConfigParameterable($this->_configTableFieldName, $varsToPush); $this->setCryptedFields(array('accessKey', 'secretKey')); $amazon_library = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'library'; //set_include_path(get_include_path() . PATH_SEPARATOR . realpath(dirname(__FILE__) . "/../../.")); set_include_path($amazon_library); $this->loadAmazonClass('OffAmazonPaymentsService_Client'); if (!JFactory::getApplication()->isSite()) { vmJsApi::jQuery(); JFactory::getDocument()->addScript(JURI::root(true) . '/plugins/vmpayment/amazon/assets/js/admin.js'); JFactory::getDocument()->addStyleSheet(JURI::root(true) . '/plugins/vmpayment/amazon/assets/css/amazon-admin.css'); } } protected function getVmPluginCreateTableSQL () { return $this->createTableSQL('Payment Amazon Table'); } function getTableSQLFields() { $SQLfields = array( 'id' => 'int(1) unsigned NOT NULL AUTO_INCREMENT', 'virtuemart_order_id' => 'int(11) UNSIGNED', 'order_number' => 'char(64)', 'virtuemart_paymentmethod_id' => 'mediumint(1) UNSIGNED', 'payment_name' => 'varchar(5000)', 'amazonOrderReferenceId' => 'char(64)', //'payment_params' => 'varchar(5000)', 'order_is_digital' => 'smallint(1)', 'payment_order_total' => 'decimal(15,5)', 'payment_currency' => 'smallint(1)', 'email_currency' => 'smallint(1)', 'recurring' => 'varchar(512)', 'recurring_number' => 'smallint(1)', 'recurring_periodicity' => 'smallint(1)', 'cost_per_transaction' => 'decimal(10,2)', 'cost_percent_total' => 'decimal(10,2)', 'tax_id' => 'smallint(1)', 'amazon_response_amazonReferenceId' => 'char(64)', 'amazon_response_amazonAuthorizationId' => 'char(64)', 'amazon_response_amazonCaptureId' => 'char(64)', 'amazon_response_amazonRefundId' => 'char(64)', 'amazon_response_state' => 'char(64)', 'amazon_response_reasonCode' => 'char(64)', 'amazon_response_reasonDescription' => 'char(64)', 'amazon_class_request_type' => 'text', 'amazon_request' => 'text', 'amazon_class_response_type' => 'text', 'amazon_response' => 'text', 'amazon_class_notification_type' => 'text', 'amazon_notification' => 'text', ); return $SQLfields; } private function renderSignInButton($cart) { if (!$this->checkConditionSignIn($cart)) { return NULL; } //$cart->setOutOfCheckout(); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $buttonWidgetImageURL = $this->getButtonWidgetImageURL(); if (!empty($buttonWidgetImageURL)) { $this->addWidgetUrlScript($client); /** we do not need that. The button or the payment method do not appear atm in the displayListFE trigger * if ($selected == $this->_currentMethod->virtuemart_paymentmethod_id) { * $checked = 'checked="checked"'; * } else { * $checked = ''; * } */ $redirect_page = $this->getSignInRedirectPage(); $onlyDigitalGoods = $this->isOnlyDigitalGoods($cart); $signInButton = $this->renderByLayout('signin', array( 'buttonWidgetImageURL' => $buttonWidgetImageURL, 'virtuemart_paymentmethod_id' => $this->_currentMethod->virtuemart_paymentmethod_id, 'sellerId' => $this->_currentMethod->sellerId, 'sign_in_css' => $this->_currentMethod->sign_in_css, 'include_amazon_css' => $this->_currentMethod->include_amazon_css, 'renderAmazonAddressBook' => (!$onlyDigitalGoods), 'redirect_page' => $redirect_page, 'layout' => $cart->layout, )); return $signInButton; } } private function redisplayAddressbookWallet($client, $cart, $order_number) { if ($cart == NULL) { $cart = VirtueMartCart::getCart(); } $this->addWidgetUrlScript($client); if (empty($this->_amazonOrderReferenceId)) { $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (empty($this->_amazonOrderReferenceId)) { $this->leaveAmazonCheckout(); return; } } $html = $this->renderByLayout('addressbook_wallet', array( 'virtuemart_paymentmethod_id' => $this->_currentMethod->virtuemart_paymentmethod_id, 'sellerId' => $this->_currentMethod->sellerId, 'addressbook_designWidth' => $this->getPixelValue($this->_currentMethod->addressbook_designWidth), 'addressbook_designHeight' => $this->getPixelValue($this->_currentMethod->addressbook_designHeight), 'wallet_designWidth' => $this->getPixelValue($this->_currentMethod->wallet_designWidth), 'wallet_designHeight' => $this->getPixelValue($this->_currentMethod->wallet_designHeight), 'include_amazon_css' => $this->_currentMethod->include_amazon_css, 'amazonOrderReferenceId' => $this->_amazonOrderReferenceId, 'renderAddressBook' => false, 'renderWalletBook' => true, 'readOnlyWidgets' => "Edit", 'captureNow' => $this->isCaptureImmediate($cart) )); $html .= $this->renderByLayout('display_wallet', array( 'virtuemart_paymentmethod_id' => $this->_currentMethod->virtuemart_paymentmethod_id, 'order_number' => $order_number, 'include_amazon_css' => $this->_currentMethod->include_amazon_css, 'useXHTML' => $cart->useXHTML, 'useSSL' => $cart->useSSL, )); return $html; } private function renderAddressbookWallet($readOnlyWidgets = false) { //if ($this->getRenderAddressDoneFromSession()) { return;} $this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); $cart = VirtueMartCart::getCart(); $this->setCartLayout($cart); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $this->addWidgetUrlScript($client); if (empty($this->_amazonOrderReferenceId)) { $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (empty($this->_amazonOrderReferenceId)) { $this->leaveAmazonCheckout(); return; } } $renderWalletBook = $cart->virtuemart_shipmentmethod_id; //$this->setRenderAddressDoneInSession(); $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); $onlyDigitalGoods = $this->isOnlyDigitalGoods($cart); $html = $this->renderByLayout('addressbook_wallet', array( 'virtuemart_paymentmethod_id' => $this->_currentMethod->virtuemart_paymentmethod_id, 'sellerId' => $this->_currentMethod->sellerId, 'include_amazon_css' => $this->_currentMethod->include_amazon_css, 'addressbook_designWidth' => $this->getPixelValue($this->_currentMethod->addressbook_designWidth), 'addressbook_designHeight' => $this->getPixelValue($this->_currentMethod->addressbook_designHeight), 'wallet_designWidth' => $this->getPixelValue($this->_currentMethod->wallet_designWidth), 'wallet_designHeight' => $this->getPixelValue($this->_currentMethod->wallet_designHeight), 'amazonOrderReferenceId' => $this->_amazonOrderReferenceId, 'renderAddressBook' => !$onlyDigitalGoods, 'renderWalletBook' => $renderWalletBook, 'readOnlyWidgets' => $readOnlyWidgets ? 'Read' : "Edit", 'captureNow' => $this->isCaptureImmediate($cart) )); echo $html; } private function checkConditionSignIn($cart) { $cart_prices = array(); $cart_prices['salesPrice'] = $cart->pricesUnformatted['billTotal']; // atm, we only display the SignIn button via the trigger plgVmOnCheckoutAdvertise //if ($this->doSignInDisplay($sign_in_display) && $this->checkConditions($cart, $this->_currentMethod, $cart_prices) && $this->checkProductConditions($product, $this->_currentMethod)) { if ($this->checkConditions($cart, $this->_currentMethod, $cart_prices)) { return true; } return false; } /** * Check if the payment conditions are fulfilled for this payment method * * @author: Valerie Isaksen * * @param $cart_prices : cart prices * @param $payment * @return true: if the conditions are fulfilled, false otherwise * */ protected function checkConditions ($cart, $method, $cart_prices) { //vmTrace('checkConditions', true); //$this->debugLog( $cart_prices['salesPrice'], 'checkConditions','debug'); $this->_currentMethod = $method; if ($this->isValidLanguage() && $this->isValidAmount($cart_prices['salesPrice']) && $this->isValidProductCategories($cart) && $this->isValidIP() ) { return true; } return false; } /** * @return bool */ private function isValidCountry ($virtuemart_country_id) { $countries = array(); if (!empty($this->_currentMethod->countries)) { if (!is_array($this->_currentMethod->countries)) { $countries[0] = $this->_currentMethod->countries; } else { $countries = $this->_currentMethod->countries; } } if (count($countries) == 0 || in_array($virtuemart_country_id, $countries)) { return TRUE; } return false; } /** * Switch for enabling / disabling Hidden Button Mode. * @return bool */ private function isValidIP() { if (empty($this->_currentMethod->ip_whitelist)) { return true; } $ip_whitelist = explode(";", $this->_currentMethod->ip_whitelist); if (in_array($_SERVER['REMOTE_ADDR'], $ip_whitelist)) { return true; } return false; } /** * $requiredKeys = array('merchantId', * 'accessKey', * 'secretKey', * 'region', * 'environment', * 'applicationName', * 'applicationVersion' */ private function getOffAmazonPaymentsService_Client () { $config['serviceURL'] = ''; $config['widgetURL'] = ''; $config['caBundleFile'] = ''; $config['clientId'] = ''; $config['merchantId'] = $this->_currentMethod->sellerId; $config['accessKey'] = $this->_currentMethod->accessKey; $config['secretKey'] = $this->_currentMethod->secretKey; $config['applicationName'] = 'VirtueMart'; $config['applicationVersion'] = '${PHING.VM.RELEASE}'; $config['region'] = $this->_currentMethod->region; $config['environment'] = $this->_currentMethod->environment; if ($this->_currentMethod->region == "other") { $prefix = $this->_currentMethod->environment; $serviceURL = $prefix . "_serviceURL"; $widgetURL = $prefix . "_widgetURL"; $config['serviceURL'] = $this->_currentMethod->$serviceURL; $config['widgetURL'] == $this->_currentMethod->$widgetURL; } try { $client = new OffAmazonPaymentsService_Client($config); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return NULL; } return $client; } private function amazonError ($message, $code = '') { $public_msg = ''; if ($this->_currentMethod->debug) { $public_msg = $message; } vmError($message . " (" . $code . ")", $public_msg); } private function getButtonWidgetImageURL () { $region = $this->_currentMethod->region; $region_europe = array('UK', 'DE'); $url = ''; if (in_array($region, $region_europe)) { if ($region == "UK") { $domain = "co.uk"; } else { $domain = "de"; } if ($this->_currentMethod->environment == 'sandbox') { $mode = "-sandbox"; } else { //TODO $mode = ""; } $url = "https://payments" . $mode . ".amazon." . $domain . "/gp/widgets/button?sellerId=" . $this->_currentMethod->sellerId . "&size=" . $this->_currentMethod->sign_in_widget_size . "&color=" . $this->_currentMethod->sign_in_widget_color . ""; } else { if ($this->_currentMethod->environment == 'sandbox') { $url = $this->_currentMethod->sandbox_signin; } else { $url = $this->_currentMethod->production_signin; } } return $url; } private function addWidgetUrlScript ($client) { if (!self::$widgetScriptLoaded) { $widgetURL = $client->getMerchantValues()->getWidgetUrl(); JHTML::script($widgetURL, false); self::$widgetScriptLoaded = true; } } /** * @return */ private function getSignInRedirectPage () { $url = 'index.php?option=com_virtuemart&view=pluginresponse&task=pluginnotification&format=raw&nt=getAmazonSessionId&pm=' . $this->_currentMethod->virtuemart_paymentmethod_id . '&Itemid=' . vRequest::getInt('Itemid') . '&lang=' . vRequest::getCmd('lang', ''); //$_amazonOrderReferenceId = $this->getAmazonOrderReferenceId(); if ($this->_amazonOrderReferenceId) { //$url .= '&session=' . $this->_amazonOrderReferenceId; } $cart = VirtueMartCart::getCart(); return JRoute::_($url, $cart->useXHTML, $cart->useSSL); } /** * @param $product * @param $productDisplay * @return bool function plgVmOnProductDisplayPayment ($product, &$productDisplay) { * * $vendorId = 1; * if ($this->getPluginMethods($vendorId) === 0) { * return FALSE; * } * * $productDisplay = $this->renderSignInButton('product', false, $product); * return TRUE; * } */ /** * @return null */ public function plgVmOnPaymentNotification () { $virtuemart_paymentmethod_id = vRequest::getInt('pm', 0); if (!($this->_currentMethod = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($this->_currentMethod->payment_element)) { return FALSE; } $notificationTask = vRequest::getCmd('nt', ''); switch ($notificationTask) { case 'getAmazonSessionId': if (!class_exists('VirtueMartCart')) { require(JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); } $cart = VirtueMartCart::getCart(false); $this->saveAmazonOrderReferenceId($cart); $this->saveBTandSTInSession($cart); $this->setCartLayout($cart, false); $this->updateCartWithDefaultAmazonAddress($cart, $this->isOnlyDigitalGoods($cart)); $this->redirectToCart(); break; case 'ipn': $this->ipn(); break; default: $this->amazonError(vmText::_('VMPAYMENT_AMAZON_INVALID_NOTIFICATION_TASK')); return; } } /** * IPNs requires SSL. All merchant cannot have SSL. A system plugin simulate a cron job */ public function plgVmRetrieveIPN () { // check if table exists $db = JFactory::getDBO(); $query = 'SHOW TABLES LIKE "' . str_replace('#__', $db->getPrefix(), $this->_tablename) . '"'; $db->setQuery($query); if (!$db->loadResult()) { return false; } $q = "SELECT * FROM " . $this->_tablename . " WHERE ( ( `amazon_class_response_type` LIKE 'OffAmazonPaymentsService_Model_ConfirmOrderReferenceResponse' AND `amazon_response_state` IN ( 'Open', 'Suspended') ) OR ( `amazon_class_response_type` LIKE 'OffAmazonPaymentsService_Model_AuthorizeResponse' AND `amazon_response_state` IN ('Pending', 'Open') ) OR ( `amazon_class_response_type` LIKE 'OffAmazonPaymentsService_Model_CaptureResponse' AND `amazon_response_state` IN ('Pending') ) OR ( `amazon_class_response_type` LIKE 'OffAmazonPaymentsService_Model_RefundResponse' AND `amazon_response_state` IN ('Pending') ) ) AND `id` in (SELECT MAX( id ) FROM " . $this->_tablename . " GROUP BY virtuemart_order_id ) ORDER BY `created_on` DESC "; $db->setQuery($q); $payments = $db->loadObjectList(); $done = array(); //$this->debugLog("
" . var_export($payments, true) . "", __FUNCTION__, 'debug'); $this->loadAmazonServicesClasses(); if (!$payments) { return; } foreach ($payments as $payment) { if (in_array($payment->order_number, $done)) { continue; } if (!$payment->amazon_request) { continue; } if (!($this->_currentMethod = $this->getVmPluginMethod($payment->virtuemart_paymentmethod_id))) { continue; } if ($payment->amazon_class_response_type == 'OffAmazonPaymentsService_Model_ConfirmOrderReferenceResponse') { $this->retrieveIPNConfirmOrderReference($payment); } elseif ($payment->amazon_class_response_type == 'OffAmazonPaymentsService_Model_RefundResponse') { $this->retrieveIPNRefund($payment); } elseif ($payment->amazon_class_response_type == 'OffAmazonPaymentsService_Model_AuthorizeResponse') { $this->retrieveIPNAuthorization($payment); } elseif ($payment->amazon_class_response_type == 'OffAmazonPaymentsService_Model_CaptureResponse') { $this->retrieveIPNCapture($payment); } $done[] = $payment->order_number; } } private function getNumberOfDays ($payments) { $created_on = strtotime($payments[0]->created_on); $now = date_create(date('Y-m-d')); $now = time(); //$number = date_diff($now, $created_on); //$number->format('%a'); $days_between = ceil(abs($created_on - $now) / 86400); return $days_between; } /** * if Open and > 180 days=> poll * if Suspended => poll * @param $payment */ private function retrieveIPNConfirmOrderReference ($payment) { $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payment->virtuemart_order_id); if (!($payments = $this->getDatasByOrderId($payment->virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return null; } if ($payment->amazon_response_state == 'Suspended' OR ($payment->amazon_response_state == 'Open' AND $this->getNumberOfDays($payments) > 180)) { $this->getAuthorizationState($payments, $order); } } /** * if Pending => poll * if closed or declined ==> fetch order * @param $payment */ private function retrieveIPNRefund ($payment) { $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payment->virtuemart_order_id); //Load the payments if (!($payments = $this->getDatasByOrderId($payment->virtuemart_order_id))) { return null; } // poll because refund state = pending $refundState = $this->getRefundState($payment, $order); if ($refundState == 'Declined' or $refundState == 'Completed') { $this->capturePayment($payments, $order); } } private function getRefundState ($payment, $order) { $amazonRefundId = $payment->amazon_response_amazonRefundId; $this->loadAmazonClass('OffAmazonPaymentsService_Model_GetRefundDetailsRequest'); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $getRefundDetailsRequest = new OffAmazonPaymentsService_Model_GetRefundDetailsRequest(); $getRefundDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getRefundDetailsRequest->setAmazonRefundId($amazonRefundId); $getRefundDetails = $client->getRefundDetails($getRefundDetailsRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return; } $this->loadHelperClass('amazonHelperGetRefundDetailsResponse'); $amazonHelperGetRefundDetailsResponse = new amazonHelperGetRefundDetailsResponse($getRefundDetails, $this->_currentMethod); $storeInternalData = $amazonHelperGetRefundDetailsResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $getRefundDetailsRequest, $getRefundDetails, NULL, NULL, $storeInternalData); return $amazonHelperGetRefundDetailsResponse->getState(); } /** * if Pending, authorization > 30 days ==> poll * If Closed, Declined ==> fetch order * @param $payment */ private function retrieveIPNAuthorization ($payment) { $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); if (!($payments = $this->getDatasByOrderId($payment->virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return null; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payment->virtuemart_order_id); if ($payment->amazon_response_state == 'Pending' OR ($payment->amazon_response_state == 'Open' AND $this->getNumberOfDays($payments) > 30)) { $amazonAuthorizationId = $this->getAmazonAuthorizationId($payments); if (!$amazonAuthorizationId) { return false; } $authorizationDetailsResponse = $this->getAuthorizationDetails($amazonAuthorizationId, $order); $this->loadHelperClass('amazonHelperGetAuthorizationDetailsResponse'); $amazonHelperAuthorizationDetailsResponse = new amazonHelperGetAuthorizationDetailsResponse($authorizationDetailsResponse, $this->_currentMethod); $authorizationState = $amazonHelperAuthorizationDetailsResponse->getState(); if ($authorizationState == 'Closed' OR $authorizationState == 'Declined') { // check if status has changed // fetch Order //$this->_amazonOrderReferenceId = $payments[0]->amazonOrderReferenceId; //$this->vmConfirmedOrder(NULL, $order, FALSE); $getAuthorizationDetailsResult = $authorizationDetailsResponse->getGetAuthorizationDetailsResult(); $getAuthorizationDetails = $getAuthorizationDetailsResult->getAuthorizationDetails(); $this->closeAuthorization($getAuthorizationDetails->getAmazonAuthorizationId(), $order); return; } if (!$authorizationDetailsResponse->isSetGetAuthorizationDetailsResult()) { return; } $getAuthorizationDetailsResult = $authorizationDetailsResponse->getGetAuthorizationDetailsResult(); if (!$getAuthorizationDetailsResult->isSetAuthorizationDetails()) { return; } $getAuthorizationDetails = $getAuthorizationDetailsResult->getAuthorizationDetails(); $this->updateAuthorizeBillingAddressInOrder($getAuthorizationDetails, $order); $amazonState = $amazonHelperAuthorizationDetailsResponse->onResponseUpdateOrderHistory($order); } } /** * if Pending => poll * if Completed, Closed, or declined ==> fetch order * @param $payment */ private function retrieveIPNCapture($payment) { $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payment->virtuemart_order_id); //Load the payments if (!($payments = $this->getDatasByOrderId($payment->virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return null; } $captureState = $this->getCaptureState($payments, $order); if ($captureState == 'Completed' OR $captureState == 'Closed' OR $captureState == 'Declined') { // will update Billing address $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $this->getAuthorization($client, NULL, $order, false); } } function plgVmOnSelfCallBE ($type, $name, &$render) { if ($name != $this->_name || $type != 'vmpayment') { return FALSE; } $action = vRequest::getCmd('action'); $virtuemart_paymentmethod_id = vRequest::getInt('virtuemart_paymentmethod_id'); //Load the method if (!($this->_currentMethod = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } $virtuemart_order_id = vRequest::getInt('virtuemart_order_id'); if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { return null; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); $this->_order_number = $this->getUniqueReferenceId($order['details']['BT']->order_number); $this->_amount = vRequest::getFloat('amount'); switch ($action) { case 'refundPayment': if ($this->canDoRefund($payments, $order)) { $this->refundPayment($payments, $order); } break; case 'capturePayment': if ($authorizationId = $this->canDoCapture($payments, $order)) { // may be we did a new authorization in case of partial capture $this->capturePayment($payments, $order); } break; case 'newAuthorization': if ($this->canDoAuthorization($payments, $order)) { $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $this->getAuthorization($client, NULL, $order, false); } break; default: vmError('VMPAYMENT_AMAZON_UPDATEPAYMENT_UNKNOWN_ACTION'); } $app = JFactory::getApplication(); $link = 'index.php?option=com_virtuemart&view=orders&task=edit&virtuemart_order_id=' . $virtuemart_order_id; $app->redirect(JRoute::_($link, FALSE)); } function plgVmOnSelfCallFE ($type, $name, &$render) { if ($name != $this->_name || $type != 'vmpayment') { return FALSE; } $action = vRequest::getCmd('action'); $virtuemart_paymentmethod_id = vRequest::getInt('virtuemart_paymentmethod_id'); //Load the method if (!($this->_currentMethod = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } $this->debugLog($action, 'plgVmOnSelfCallFE', 'debug'); if (!class_exists('VirtueMartCart')) { require(JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); } switch ($action) { case 'updateCartWithAmazonAddress': //$client = $this->getOffAmazonPaymentsService_Client(); //$this->setOrderReferenceDetails() $return = $this->updateCartWithAmazonAddress(); $json = array(); $json['reload'] = $return['error']; $json['error_msg'] = ''; if (isset($return['error_msg'])) { $json['error_msg'] = $this->rendererErrorMessage($return['error_msg']); } JResponse::setHeader('Cache-Control', 'no-cache, must-revalidate'); JResponse::setHeader('Expires', 'Mon, 6 Jul 2000 10:00:00 GMT'); // Set the MIME type for JSON output. $document = JFactory::getDocument(); $document->setMimeEncoding('application/json'); JResponse::setHeader('Content-Disposition', 'attachment;filename="amazon.json"', TRUE); JResponse::sendHeaders(); echo json_encode($json); jExit(); //JFactory::getApplication()->close(); break; case 'leaveAmazonCheckout': $this->leaveAmazonCheckout(); $json = array(); JResponse::setHeader('Cache-Control', 'no-cache, must-revalidate'); JResponse::setHeader('Expires', 'Mon, 6 Jul 2000 10:00:00 GMT'); // Set the MIME type for JSON output. $document = JFactory::getDocument(); $document->setMimeEncoding('application/json'); JResponse::setHeader('Content-Disposition', 'attachment;filename="amazon.json"', TRUE); JResponse::sendHeaders(); echo json_encode($json); jExit(); break; case 'resetAmazonReferenceId': $this->clearAmazonSession(); break; case 'onInvalidPaymentNewAuthorization': $html = $this->onInvalidPaymentNewAuthorization(); echo $html; break; default: $this->amazonError(vmText::_('VMPAYMENT_AMAZON_INVALID_NOTIFICATION_TASK')); return; } } function rendererErrorMessage($msg) { return '
" . var_export($constraint, true) . "", __FUNCTION__, 'debug'); $this->renderAddressbookWallet('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'); } /** * @param $cart * @param $order * @return bool|null */ public function plgVmConfirmedOrder ($cart, $order) { if (!($this->_currentMethod = $this->getVmPluginMethod($order['details']['BT']->virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($this->_currentMethod->payment_element)) { return FALSE; } $this->setInConfirmOrder($cart); $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (!$this->_amazonOrderReferenceId) { $this->onErrorRedirectToCart(); return FALSE; } $client = $this->getOffAmazonPaymentsService_Client(); // the amount saved is in payment currency $this->_amount = $this->getTotalInPaymentCurrency($client, $order['details']['BT']->order_total, $order['details']['BT']->order_currency); $this->_is_digital = $this->isOnlyDigitalGoods($cart); $this->storeAmazonInternalData($order, NULL, NULL, NULL, $this->renderPluginName($this->_currentMethod), NULL, $this->_amazonOrderReferenceId, $this->_currentMethod); $this->_order_number = $order['details']['BT']->order_number; $html = $this->vmConfirmedOrder($cart, $order, false); vRequest::setVar('html', $html); vRequest::setVar('display_title', false); } /** * Confirmed Order also when in synchronous mode, and InvalidPaymentMethod * @param $cart * @param $order * @return bool|string */ private function vmConfirmedOrder ($cart, $order, $orderReferenceModifiable = true) { $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } // if $cart=NULL may be coming from plgVmRetrieveIPN if ($cart) { if (!$this->setOrderReferenceDetails($client, $cart, $order)) { $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } } //confirmOrderReference if (!$this->confirmOrderReference($client, $order)) { $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } // getorderdetails & address email if (!$this->updateBuyerInOrder($client, $cart, $order)) { $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } /* why do i have that ? */ if ($cart) { $redirect = true; } else { $redirect = false; } $redirect = true; // at this point, since the authorization and capturing takes additional time to process // let's do that with a trigger if (!($amazonAuthorizationId = $this->getAuthorization($client, $cart, $order, $redirect))) { // getAuhtorization returns false if the the wallet needs to be displayed again $cart->_inConfirm = false; $html = $this->redisplayAddressbookWallet($client, $cart, $order['details']['BT']->order_number); return $html; } if (!class_exists('CurrencyDisplay')) { require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'currencydisplay.php'); } VmConfig::loadJLang('com_virtuemart_orders', TRUE); $success = true; $html = $this->renderByLayout('response', array( "success" => $success, "amazonOrderId" => $this->getAmazonOrderReferenceIdFromSession(), "order" => $order, 'include_amazon_css' => $this->_currentMethod->include_amazon_css, )); $this->leaveAmazonCheckout(); if (!$cart) { $cart = VirtueMartCart::getCart(); } $cart->emptyCart(); return $html; } /** * @param $order * @param $request * @param $response * @param $notification * @param null $payment_name * @param null $amazonParams * @return array */ private function storeAmazonInternalData ($order, $request, $response, $notification = NULL, $payment_name = NULL, $amazonParams = NULL, $amazonOrderReferenceId = NULL) { $db_values['order_number'] = $order['details']['BT']->order_number; $db_values['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id; $db_values['virtuemart_paymentmethod_id'] = $this->_currentMethod->virtuemart_paymentmethod_id; $db_values['order_is_digital'] = $this->_is_digital; $db_values['payment_order_total'] = $this->_amount; $db_values['payment_currency'] = $order['details']['BT']->user_currency_id; $db_values['amazon_request'] = $request ? serialize($request) : ""; $db_values['amazon_class_request_type'] = $request ? get_class($request) : ''; $db_values['amazon_response'] = $response ? serialize($response) : ""; $db_values['amazon_class_response_type'] = $response ? get_class($response) : ''; $db_values['amazon_notification'] = $notification ? serialize($notification) : ""; $db_values['amazon_class_notification_type'] = $notification ? get_class($notification) : ''; $db_values['amazonOrderReferenceId'] = $amazonOrderReferenceId ? $amazonOrderReferenceId : ''; //$db_values['payment_params'] = $this->_currentMethod; $db_values['payment_name'] = $payment_name; if ($amazonParams) { $amazonParamsArray = (array)($amazonParams); $db_values = array_merge($db_values, $amazonParamsArray); } //$preload=true preload the data here too preserve not updated data return $this->storePSPluginInternalData($db_values, $this->_tablepkey, 0); } /** * @return mixed */ // TODO: address line 3, district private function updateBuyerInOrder ($client, $cart, $order) { $orderModel = VmModel::getModel('orders'); $BT['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id; $order_userinfosTable = $orderModel->getTable('order_userinfos'); $getOrderReferenceDetailsResponse = $this->getOrderReferenceDetails($client); $getOrderReferenceDetailsResult = $getOrderReferenceDetailsResponse->getGetOrderReferenceDetailsResult(); $orderReferenceDetails = $getOrderReferenceDetailsResult->getOrderReferenceDetails(); if ($orderReferenceDetails->isSetBuyer()) { $buyer = $orderReferenceDetails->getBuyer(); $BTFromAmazon = $this->getUserInfoFromAmazon($buyer, '', false, true); $BTFromAmazon['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id; $BTFromAmazon['address_type'] = 'BT'; $this->debugLog("
" . var_export($BTFromAmazon, true) . "", __FUNCTION__ . ' BT', 'debug'); $order_userinfosTable->emptyCache(); $order_userinfosTable->load($order['details']['BT']->virtuemart_order_id, 'virtuemart_order_id', " AND address_type='BT'"); if (!$order_userinfosTable->bindChecknStore($BTFromAmazon, true)) { vmError($order_userinfosTable->getError()); return false; } } // at this step, we should get it from amazon $onlyDigitalGoods = $this->isOnlyDigitalGoods($cart); if (!$onlyDigitalGoods) { $physicalDestination = $orderReferenceDetails->getDestination()->getPhysicalDestination(); if ($physicalDestination) { $ST = $this->getUserInfoFromAmazon($physicalDestination); $ST['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id; $ST['address_type'] = 'ST'; $order_userinfosTable->emptyCache(); // check if ST is there $query="SELECT `#__virtuemart_order_userinfos`.* FROM `#__virtuemart_order_userinfos` WHERE `#__virtuemart_order_userinfos`.`virtuemart_order_id` = ".$order['details']['BT']->virtuemart_order_id." AND address_type='ST'"; $db = JFactory::getDBO(); $db->setQuery($query); if(!$db->loadResult()) { $order_userinfosTable=$orderModel->getTable('order_userinfos'); } $order_userinfosTable->load($order['details']['BT']->virtuemart_order_id, 'virtuemart_order_id', " AND address_type='ST'"); if (!$order_userinfosTable->bindChecknStore($ST, true)) { vmError($order_userinfosTable->getError()); return false; } $this->debugLog("
" . var_export($ST, true) . "", __FUNCTION__ . ' ST', 'debug'); } } return true; } private function getUserInfoFromAmazon ($amazonAddress, $prefix = '', $all = true, $getEmail = false) { if ($amazonAddress->isSetName()) { $userInfoData[$prefix . 'last_name'] = $amazonAddress->getName(); $userInfoData[$prefix . 'first_name'] = ''; } if ($getEmail AND $amazonAddress->isSetEmail()) { $userInfoData['email'] = $amazonAddress->getEmail(); } if ($amazonAddress->isSetPhone()) { $userInfoData['phone_1'] = $amazonAddress->getPhone(); } if ($all) { if ($amazonAddress->isSetAddressLine1()) { $userInfoData[$prefix . 'address_1'] = $amazonAddress->getAddressLine1(); if ($amazonAddress->isSetAddressLine2()) { $userInfoData[$prefix . 'address_2'] = $amazonAddress->getAddressLine2(); } if ($amazonAddress->isSetAddressLine3()) { $userInfoData[$prefix . 'address_2'] .= ", " . $amazonAddress->getAddressLine3(); } } else { if ($amazonAddress->isSetAddressLine2()) { $userInfoData[$prefix . 'address_1'] = $amazonAddress->getAddressLine2(); } if ($amazonAddress->isSetAddressLine3()) { $userInfoData[$prefix . 'address_2'] = $amazonAddress->getAddressLine3(); } } if ($amazonAddress->isSetCity()) { $userInfoData[$prefix . 'city'] = $amazonAddress->getCity(); } if ($amazonAddress->isSetCounty()) { //$userInfoData['county'] = $amazonAddress->getCounty(); } if ($amazonAddress->isSetDistrict()) { //$userInfoData['district'] = $amazonAddress->GetDistrict(); } if ($amazonAddress->isSetStateOrRegion()) { $stateId = shopFunctions::getStateIDByName($amazonAddress->GetStateOrRegion()); if ($stateId) { $userInfoData[$prefix . 'virtuemart_state_id'] = $stateId; } else { $userInfoData[$prefix . 'virtuemart_state_id'] = 0; } } if ($amazonAddress->isSetPostalCode()) { $userInfoData[$prefix . 'zip'] = $amazonAddress->GetPostalCode(); } if ($amazonAddress->isSetCountryCode()) { $userInfoData[$prefix . 'virtuemart_country_id'] = shopFunctions::getCountryIDByName($amazonAddress->GetCountryCode()); } } return $userInfoData; } function getAmazonShipmentAddress() { $this->loadAmazonClass('OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest'); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $getOrderReferenceDetailsRequest = new OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest(); $getOrderReferenceDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getOrderReferenceDetailsRequest->setAmazonOrderReferenceId($this->getAmazonOrderReferenceIdFromSession()); $referenceDetailsResultWrapper = $client->getOrderReferenceDetails($getOrderReferenceDetailsRequest); $physicalDestination = $referenceDetailsResultWrapper->GetOrderReferenceDetailsResult->getOrderReferenceDetails()->getDestination()->getPhysicalDestination(); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return; } return $physicalDestination; } function getAuthorizationDetails($amazonAuthorizationId, $order) { $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $getAuthorizationDetailsRequest = new OffAmazonPaymentsService_Model_GetAuthorizationDetailsRequest(); $getAuthorizationDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getAuthorizationDetailsRequest->setAmazonAuthorizationId($amazonAuthorizationId); $getAuthorizationDetailsResponse = $client->getAuthorizationDetails($getAuthorizationDetailsRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return NULL; } $this->loadHelperClass('amazonHelperGetAuthorizationDetailsResponse'); $amazonHelperGetAuthorizationDetailsResponse = new amazonHelperGetAuthorizationDetailsResponse($getAuthorizationDetailsResponse, $this->_currentMethod); $storeInternalData = $amazonHelperGetAuthorizationDetailsResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $getAuthorizationDetailsRequest, $getAuthorizationDetailsResponse, NULL, NULL, $storeInternalData); return $getAuthorizationDetailsResponse; } private function getCaptureDetails($amazonCaptureId, $order) { $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $getCaptureDetailsRequest = new OffAmazonPaymentsService_Model_GetCaptureDetailsRequest(); $getCaptureDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getCaptureDetailsRequest->setAmazonCaptureId($amazonCaptureId); $getCaptureDetails = $client->getCaptureDetails($getCaptureDetailsRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return; } $this->loadHelperClass('amazonHelperGetCaptureDetailsResponse'); $amazonHelperGetCaptureDetailsResponse = new amazonHelperGetCaptureDetailsResponse($getCaptureDetails, $this->_currentMethod); $storeInternalData = $amazonHelperGetCaptureDetailsResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $getCaptureDetailsRequest, $getCaptureDetails, NULL, NULL, $storeInternalData); return $getCaptureDetails; } /* private function getAmazonBillingAddress ($amazonAuthorizationId) { $getAuthorizationDetails = $this->getAuthorizationDetails($amazonAuthorizationId); $billingAddress = $getAuthorizationDetails->getGetAuthorizationDetailsResult()->getAuthorizationDetails()->getAuthorizationBillingAddress(); return $billingAddress; } */ /** * If we are going back to the cart because of InvalidPaymentMethod, then the order reference is not anylonger in a draft state * @return bool */ private function setOrderReferenceDetails($client, $cart, $order = NULL) { $this->loadAmazonClass('OffAmazonPaymentsService_Model_OrderReferenceAttributes'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_OrderTotal'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_SellerOrderAttributes'); if ($order) { $amountInCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total, $order['details']['BT']->user_currency_id); $amount = $amountInCurrency['value']; } else { $amount = $this->getTotalInPaymentCurrency($client, $cart->pricesUnformatted['billTotal'], $cart->pricesCurrency); } //$_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (empty($this->_amazonOrderReferenceId)) { $this->amazonError(__FUNCTION__ . ' setOrderReferenceDetails, No $_amazonOrderReferenceId'); return FALSE; } try { $setOrderReferenceDetailsRequest = new OffAmazonPaymentsService_Model_SetOrderReferenceDetailsRequest(); $setOrderReferenceDetailsRequest->setSellerId($this->_currentMethod->sellerId); $setOrderReferenceDetailsRequest->setAmazonOrderReferenceId($this->_amazonOrderReferenceId); $setOrderReferenceDetailsRequest->setOrderReferenceAttributes(new OffAmazonPaymentsService_Model_OrderReferenceAttributes()); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->setOrderTotal(new OffAmazonPaymentsService_Model_OrderTotal()); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->getOrderTotal()->setCurrencyCode($this->getCurrencyCode3($client)); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->getOrderTotal()->setAmount($amount); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->setSellerNote($this->getSellerNote()); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->setSellerOrderAttributes(new OffAmazonPaymentsService_Model_SellerOrderAttributes()); if ($order) { $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->getSellerOrderAttributes()->setSellerOrderId($order['details']['BT']->order_number); } $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->getSellerOrderAttributes()->setStoreName($this->getStoreName()); //$setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->getSellerOrderAttributes()->setCustomInformation($order['details']['BT']->customer_note); $setOrderReferenceDetailsRequest->getOrderReferenceAttributes()->setPlatformId($this->getPlatformId()); $setOrderReferenceDetailsResponse = $client->setOrderReferenceDetails($setOrderReferenceDetailsRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); $this->clearAmazonSession(); return FALSE; } $this->debugLog("
" . var_export($setOrderReferenceDetailsRequest, true) . "", __FUNCTION__, 'debug'); $this->debugLog("
" . var_export($setOrderReferenceDetailsResponse, true) . "", __FUNCTION__, 'debug'); return $setOrderReferenceDetailsResponse; } /** * @return bool */ private function getOrderReferenceDetails($client) { $this->loadAmazonClass('OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest'); //$_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (empty($this->_amazonOrderReferenceId)) { $this->amazonError(__FUNCTION__ . ', No $_amazonOrderReferenceId'); return FALSE; } try { $getOrderReferenceDetailsRequest = new OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest(); $getOrderReferenceDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getOrderReferenceDetailsRequest->setAmazonOrderReferenceId($this->_amazonOrderReferenceId); $getOrderReferenceDetailsResponse = $client->getOrderReferenceDetails($getOrderReferenceDetailsRequest); $this->debugLog("
" . var_export($getOrderReferenceDetailsRequest, true) . "", __FUNCTION__, 'debug'); $this->debugLog("
" . var_export($getOrderReferenceDetailsResponse, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); $this->clearAmazonSession(); return FALSE; } return $getOrderReferenceDetailsResponse; } /** * @param $client * @param $total * @param $backToPricesCurrency * @return array */ private function getTotalInPaymentCurrency($client, $total, $backToPricesCurrency) { if (!class_exists('CurrencyDisplay')) { require(JPATH_VM_ADMINISTRATOR . '/helpers/currencydisplay.php'); } $virtuemart_currency_id = $this->getCurrencyId($client); $totalInPaymentCurrency = vmPSPlugin::getAmountValueInCurrency($total, $virtuemart_currency_id); //$this->debugLog($totalInPaymentCurrency, __FUNCTION__, 'debug'); $cd = CurrencyDisplay::getInstance($backToPricesCurrency); return $totalInPaymentCurrency; } /** * @param $client * @return int */ private function getCurrencyId($client) { $currencyCode3 = $this->getCurrencyCode3($client); $virtuemart_currency_id = shopFunctions::getCurrencyIDByName($currencyCode3); return $virtuemart_currency_id; } /** * @param $client * @return mixed */ private function getCurrencyCode3($client) { return $client->getMerchantValues()->getCurrency(); } /** * SellerNote can contain Sandbox Simulation string to test the Constraints * @return null|string */ private function getSellerNote() { return NULL; return $this->getSetOrderReferenceSandboxSimulationString(); } /** * @return string */ private function getSellerAuthorizationNote() { if ($this->_currentMethod->environment != 'sandbox' AND empty($this->_currentMethod->sandbox_error_simulation_auth)) { return NULL; } return $this->getSandboxSimulationString($this->_currentMethod->sandbox_error_simulation_auth); } /** * @return null|string */ private function getSellerRefundNote() { if ($this->_currentMethod->environment != 'sandbox' AND empty($this->_currentMethod->sandbox_error_simulation_refund)) { return NULL; } return $this->getSandboxSimulationString($this->_currentMethod->sandbox_error_simulation_refund); } /** * */ private function getSetOrderReferenceSandboxSimulationString() { return NULL; if ($this->_currentMethod->environment != 'sandbox' AND empty($this->_currentMethod->sandbox_error_simulation)) { return NULL; } $setOrderReferenceSandboxSimulation = array( 'InvalidPaymentMethod', //'PaymentMethodNotAllowed', // 'AmazonRejected', // 'TransactionTimedOut', // 'ExpiredUnused', // 'AmazonClosed', ); return $this->getSandboxSimulationString($setOrderReferenceSandboxSimulation, $this->_currentMethod->sandbox_error_simulation); } /** * * @param $authorizedSimulationReasons * @param $reason * @return null|string */ private function getSandboxSimulationString ($reason) { if ($this->_currentMethod->environment != 'sandbox' or empty($reason)) { return NULL; } $sandboxSimulationStrings = array( 'InvalidPaymentMethod' => '{"SandboxSimulation":{"State":"Declined","ReasonCode":"InvalidPaymentMethod"}}', //'PaymentMethodNotAllowed' => '{"SandboxSimulation": {"State":"Declined","ReasonCode":"InvalidPaymentMethod","PaymentMethodUpdateTimeInMins":100}}', 'AmazonRejected' => '{"SandboxSimulation":{"State":"Declined","ReasonCode":"AmazonRejected" }}', 'TransactionTimedOut' => '{"SandboxSimulation":{"State":"Declined","ReasonCode":"TransactionTimedOut"}}', 'ExpiredUnused' => '{"SandboxSimulation":{"State":"Declined","ReasonCode":"ExpiredUnused" ,"ExpirationTimeInMins":1}}', 'AmazonClosed' => '{"SandboxSimulation":{"State":"Closed", "ReasonCode":"AmazonClosed"}}', 'Pending' => '{"SandboxSimulation":{"State":"Pending"}}', ); $simulationString = $sandboxSimulationStrings[$reason]; return $simulationString; } /** * @return mixed */ private function getStoreName() { if (!class_exists('VirtueMartModelVendor')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'vendor.php'); } $virtuemart_vendor_id = 1; $vendorModel = VmModel::getModel('vendor'); $vendor = $vendorModel->getVendor($virtuemart_vendor_id); return $vendor->vendor_store_name; } /** * @return null|string */ private function getPlatformId () { if ($this->_currentMethod->region == "UK") { return "AA3KB5JD2CWIH"; } if ($this->_currentMethod->region == "DE") { return "A264YAJNGET7NB"; } return NULL; } private function onErrorRedirectToCart ($msg = NULL) { if (!$msg) { $msg = vmText::sprintf('VMPAYMENT_AMAZON_ERROR_TRY_AGAIN', $this->getVendorLink()); } else { } $this->redirectToCart($msg, true); } private function redirectToCart ($msg = NULL, $clearAmazonSession = false) { if ($clearAmazonSession) { $this->clearAmazonSession(); } $app = JFactory::getApplication(); $app->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart&Itemid=' . vRequest::getInt('Itemid'), false), $msg); } private function getVendorLink () { return JRoute::_('index.php?option=com_virtuemart&view=vendor&layout=contact&virtuemart_vendor_id=' . $this->_currentMethod->virtuemart_vendor_id); } /** * */ private function confirmOrderReference($client, $order) { $this->loadHelperClass('amazonHelperConfirmOrderReferenceResponse'); try { $confirmOrderReferenceRequest = new OffAmazonPaymentsService_Model_ConfirmOrderReferenceRequest(); $confirmOrderReferenceRequest->setAmazonOrderReferenceId($this->_amazonOrderReferenceId); $confirmOrderReferenceRequest->setSellerId($this->_currentMethod->sellerId); $confirmOrderReferenceResponse = $client->confirmOrderReference($confirmOrderReferenceRequest); $this->debugLog("
" . var_export($confirmOrderReferenceRequest, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { // here we may have an error code when "Invalid Payment Method", "The OrderReferenceId xxx has constraints PaymentPlanNotSet and cannot be confirmed." $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return false; } $this->debugLog("
" . var_export($confirmOrderReferenceResponse, true) . "", __FUNCTION__, 'debug'); $amazonHelperconfirmOrderReferenceResponse = new amazonHelperConfirmOrderReferenceResponse($confirmOrderReferenceResponse, $this->_currentMethod); $amazonHelperconfirmOrderReferenceResponse->onResponseUpdateOrderHistory($order); $storeInternalData = $amazonHelperconfirmOrderReferenceResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $confirmOrderReferenceRequest, $confirmOrderReferenceResponse, NULL, NULL, $storeInternalData); return true; } /** * @param $client * @param $cart * @param $order */ private function getAuthorization ($client, $cart, $order, $redirect = true) { $shouldRetry = false; $retries = 0; $this->loadAmazonClass('OffAmazonPaymentsService_Model_AuthorizeRequest'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_Price'); $this->loadHelperClass('amazonHelperAuthorizeResponse'); do { $authorizeRequest = new OffAmazonPaymentsService_Model_AuthorizeRequest(); $authorizeRequest->setAmazonOrderReferenceId($this->_amazonOrderReferenceId); $authorizeRequest->setSellerId($this->_currentMethod->sellerId); $authorizeRequest->setAuthorizationReferenceId($this->_order_number); $authorizeRequest->setSellerAuthorizationNote($this->getSellerAuthorizationNote()); $authorizeRequest->setTransactionTimeout($this->getAuthorizationTransactionTimeout()); // directly do the capture without the need to call the Capture Request if ($this->isCaptureImmediate($cart)) { $authorizeRequest->setCaptureNow(true); } else { $authorizeRequest->setCaptureNow(false); } $authorizeRequest->setAuthorizationAmount(new OffAmazonPaymentsService_Model_Price()); //$this->_amount is already on payment currency $authorizeRequest->getAuthorizationAmount()->setAmount($this->_amount); $authorizeRequest->getAuthorizationAmount()->setCurrencyCode($this->getCurrencyCode3($client)); try { $authorizeResponse = $client->authorize($authorizeRequest); $amazonAuthorizationId = $authorizeResponse->getAuthorizeResult()->getAuthorizationDetails()->getAmazonAuthorizationId(); //$this->debugLog("ERREUR
" . var_export($authorizeRequest, true) . "", __FUNCTION__, 'debug'); //$this->debugLog("ERREUR
" . var_export($authorizeResponse, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { $msg = "An exception was thrown when trying to do the authorization:" . $e->getMessage() . "\n" . $e->getTraceAsString(); while ($e = $e->getPrevious()) { $msg .= ("Caused by: " . $e->getMessage() . "\n" . $e->getTraceAsString() . ""); $msg .= "\n"; } if ($redirect) { if (!$cart) { $cart = VirtueMartCart::getCart(); } $cart->setOutOfCheckout(); $this->debugLog($msg, __FUNCTION__ . " Exception", 'error'); $this->amazonError(__FUNCTION__ . ' ' . $msg); $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } return false; } if ($authorizationDetails = $this->getAuthorizeDetailsFromAuthorizeResponse($authorizeResponse)) { $this->updateAuthorizeBillingAddressInOrder($authorizationDetails, $order); } $amazonHelperAuthorizeResponse = new amazonHelperAuthorizeResponse($authorizeResponse, $this->_currentMethod); $amazonState = $amazonHelperAuthorizeResponse->onResponseUpdateOrderHistory($order); $storeInternalData = $amazonHelperAuthorizeResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $authorizeRequest, $authorizeResponse, NULL, $this->renderPluginName($this->_currentMethod), $storeInternalData); $reasonCode = $authorizeResponse->getAuthorizeResult()->getAuthorizationDetails()->getAuthorizationStatus()->getReasonCode(); if ($redirect) { if ($amazonState == 'Declined' && $reasonCode == 'InvalidPaymentMethod' && $this->_currentMethod->soft_decline) { $this->incrementRetryInvalidPaymentMethodInSession(); return false; } elseif (($amazonState == 'Open' && $reasonCode == 'AmazonRejected') or ($amazonState == 'Declined' && $reasonCode == 'TransactionTimedOut')) { if ($retries < 2) { $shouldRetry = true; $retries++; } else { $cart->setOutOfCheckout(); $this->leaveAmazonCheckout(); $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } } elseif ($amazonState == 'Declined') { $cart->setOutOfCheckout(); $this->leaveAmazonCheckout(); $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); } elseif ($amazonState == 'Closed' && $reasonCode == 'MaxCapturesProcessed') { $getAuthorizationDetails = $authorizeResponse->getAuthorizeResult()->getAuthorizationDetails(); $this->closeAuthorization($getAuthorizationDetails->getAmazonAuthorizationId(), $order); } } } while ($shouldRetry and $redirect); return $amazonAuthorizationId; } private function onInvalidPaymentNewAuthorization () { $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); $this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession(); if (!$this->_amazonOrderReferenceId) { $this->onErrorRedirectToCart(); return FALSE; } $retryInvalidPaymentMethod = $this->incrementRetryInvalidPaymentMethodInSession(); if ($retryInvalidPaymentMethod > 3) { //echo "TOO MANY RETRIES STOP"; $this->leaveAmazonCheckout(); $this->redirectToCart(vmText::_('VMPAYMENT_AMAZON_SELECT_ANOTHER_PAYMENT'), true); return; } if (!($order_number = vRequest::getWord('order_number'))) { $this->debugLog('no order number in submit', __FUNCTION__, 'debug'); return true; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { $this->debugLog('no getOrderIdByOrderNumber: ' . $order_number, __FUNCTION__, 'debug'); return true; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); $this->_amount = $this->getTotalInPaymentCurrency($this->getOffAmazonPaymentsService_Client(), $order['details']['BT']->order_total, $order['details']['BT']->order_currency); $this->_order_number = $this->getUniqueReferenceId($order['details']['BT']->order_number); $this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); $cart = $cart = VirtueMartCart::getCart(); $html = $this->vmConfirmedOrder($cart, $order, false); return $html; } function getAuthorizeDetailsFromAuthorizeResponse ($authorizeResponse) { if ($authorizeResponse == NULL) { vmError('Amazon : programming error ' . __FUNCTION__); return false; } if (!$authorizeResponse->isSetAuthorizeResult()) { return; } $authorizeResult = $authorizeResponse->getAuthorizeResult(); if (!$authorizeResult->isSetAuthorizationDetails()) { return; } $authorizationDetails = $authorizeResult->getAuthorizationDetails(); return $authorizationDetails; } function updateAuthorizeBillingAddressInOrder ($authorizationDetails, $order) { if (!$authorizationDetails->isSetAuthorizationBillingAddress()) { return; } $authorizationBillingAddress = $authorizationDetails->getAuthorizationBillingAddress(); $BT = $this->getUserInfoFromAmazon($authorizationBillingAddress); $orderModel = VmModel::getModel('orders'); $BT['virtuemart_order_id'] = $order['details']['BT']->virtuemart_order_id; $order_userinfosTable = $orderModel->getTable('order_userinfos'); $BT['address_type'] = 'BT'; $order_userinfosTable->emptyCache(); $order_userinfosTable->load($order['details']['BT']->virtuemart_order_id, 'virtuemart_order_id', " AND address_type='BT'"); if (!$order_userinfosTable->bindChecknStore($BT, true)) { vmError($order_userinfosTable->getError()); return false; } } /** * @return int */ function getAuthorizationTransactionTimeout () { if ($this->_currentMethod->erp_mode == "erp_mode_disabled") { if ($this->_currentMethod->authorization_mode_erp_disabled == "automatic_synchronous") { return 0; } else { return self::AUTHORIZE_TRANSACTION_TIMEOUT; } } else { if ($this->_currentMethod->authorization_mode_erp_enabled == "automatic_synchronous") { return 0; } else { return self::AUTHORIZE_TRANSACTION_TIMEOUT; } } } public function plgVmOnUpdateOrderPayment (&$order, $old_order_status) { static $updateOrderPaymentNumber = 0; // we don't do anything from the front end if (JFactory::getApplication()->isSite()) { //return NULL; } //Load the method if (!($this->_currentMethod = $this->getVmPluginMethod($order->virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($this->_currentMethod->payment_element)) { return NULL; } if ($this->isERPModeEnabled() ) { return; } if (!$this->isValidUpdateOrderStatus($order->order_status)) { if (!JFactory::getApplication()->isSite()) { vmError(vmText::_('VMPAYMENT_AMAZON_UPDATEPAYMENT_NO_ACTION')); } return; } if ($updateOrderPaymentNumber > 10) { // todo: display message $updateOrderPaymentNumber = 0; sleep(5); } //Load the payments if (!($payments = $this->getDatasByOrderId($order->virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return null; } $orderModel = VmModel::getModel('orders'); $orderModelData = $orderModel->getOrder($order->virtuemart_order_id); $this->_amount = $payments[0]->payment_order_total; // in payment currency $this->_order_number = $this->getUniqueReferenceId($orderModelData['details']['BT']->order_number); if ($order->order_status == $this->_currentMethod->status_refunded and $this->canDoRefund($payments, $orderModelData)) { return $this->refundPayment($payments, $orderModelData); } elseif ($order->order_status == $this->_currentMethod->status_capture and $this->canDoCapture($payments, $orderModelData)) { return $this->capturePayment($payments, $orderModelData); } elseif ($order->order_status == $this->_currentMethod->status_cancel and $this->canDoCancel($payments, $orderModelData)) { return $this->cancelPayment($payments, $orderModelData); } $updateOrderPaymentNumber++; return false; } /** * @param $payments * @return bool */ private function getCaptureState ($payments, $order) { $amazonCaptureId = $this->getAmazonCaptureId($payments); if (!$amazonCaptureId) { return false; } $captureDetailsResponse = $this->getCaptureDetails($amazonCaptureId, $order); $this->loadHelperClass('amazonHelperGetCaptureDetailsResponse'); $amazonHelperCaptureDetailsResponse = new amazonHelperGetCaptureDetailsResponse($captureDetailsResponse, $this->_currentMethod); $captureState = $amazonHelperCaptureDetailsResponse->getState(); $storeInternalData = $amazonHelperCaptureDetailsResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, NULL, $captureDetailsResponse, NULL, $this->renderPluginName($this->_currentMethod), $storeInternalData); return $captureState; } /** * @param $payments * @return bool */ private function canDoCancel ($payments, $order) { $lastPayments = $payments[count($payments) - 1]; // return when InvalidPaymentMethod if ($lastPayments->amazon_response_state != "Suspended") { return true; } return false; } /** * @param $payments * @return bool */ private function canDoRefund ($payments, $order) { $captureState = $this->getCaptureState($payments, $order); if ($captureState === false) { vmInfo('VMPAYMENT_AMAZON_UPDATEPAYMENT_NOAMAZONCAPTUREID'); return; } if ($captureState != 'Completed') { vmInfo(vmText::sprintf('VMPAYMENT_AMAZON_UPDATEPAYMENT_CANTDOREFUND', $captureState)); return false; } return true; } private function getAuthorizationState ($payments, $order) { $amazonAuthorizationId = $this->getAmazonAuthorizationId($payments); if (!$amazonAuthorizationId) { return false; } $authorizationDetailsResponse = $this->getAuthorizationDetails($amazonAuthorizationId, $order); if (!$authorizationDetailsResponse) { return NULL; } //catch errors $this->loadHelperClass('amazonHelperGetAuthorizationDetailsResponse'); $amazonHelperAuthorizationDetailsResponse = new amazonHelperGetAuthorizationDetailsResponse($authorizationDetailsResponse, $this->_currentMethod); $authorizationState = $amazonHelperAuthorizationDetailsResponse->getState(); $storeInternalData = $amazonHelperAuthorizationDetailsResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, NULL, $authorizationDetailsResponse, NULL, $this->renderPluginName($this->_currentMethod), $storeInternalData); return $authorizationState; } /** * if authorization object is in Open State, then the funds can be captured */ private function canDoCapture ($payments, $order) { $authorizationState = $this->getAuthorizationState($payments, $order); if (!$authorizationState) { return false; } if ($authorizationState != 'Open') { vmInfo(vmText::sprintf('VMPAYMENT_AMAZON_UPDATEPAYMENT_CANTDOCAPTURE', $authorizationState)); return false; } return true; } /** * if authorization object is in Open State, then the funds can be captured */ private function canDoAuthorization ($payments, $order) { $this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromPayments($payments); $orderReferencestate = $this->getOrderReferenceState(); if ($orderReferencestate != 'Open') { return false; } return true; } private function configCanDoAuthorization () { if ($this->_currentMethod->erp_mode == "erp_mode_disabled" OR ($this->_currentMethod->erp_mode == "erp_mode_enabled" AND $this->_currentMethod->authorization_mode_erp_enabled != "authorization_done_by_erp")) { return true; } else { return false; } } /** * @param $payments * @param $order * if orderstate == Open, Suspended ==> closeOrderReference * of orderstate= draft, open, , and no pending, completed, closed captures CancelOrderReference */ private function cancelPayment ($payments, $order) { $cancelOrderReferenceRequest = new OffAmazonPaymentsService_Model_CancelOrderReferenceRequest(); $amazonOrderReferenceId = $this->getAmazonOrderReferenceId($payments); $cancelOrderReferenceRequest->setSellerId($this->_currentMethod->sellerId); $cancelOrderReferenceRequest->setAmazonOrderReferenceId($amazonOrderReferenceId); $client = $this->getOffAmazonPaymentsService_Client(); try { $client->cancelOrderReference($cancelOrderReferenceRequest); $this->debugLog("
" . var_export($cancelOrderReferenceRequest, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return FALSE; } $this->storeAmazonInternalData($order, $cancelOrderReferenceRequest, NULL, NULL, $this->renderPluginName($this->_currentMethod), NULL, NULL, $this->_amount); } private function capturePayment ($payments, $order) { $amazonAuthorizationId = $this->getAmazonAuthorizationId($payments); $this->loadAmazonClass('OffAmazonPaymentsService_Model_CaptureRequest'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_Price'); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $captureRequest = new OffAmazonPaymentsService_Model_CaptureRequest(); $captureRequest->setSellerId($this->_currentMethod->sellerId); $captureRequest->setAmazonAuthorizationId($amazonAuthorizationId); $captureRequest->setCaptureReferenceId($this->_order_number); $captureRequest->setCaptureAmount(new OffAmazonPaymentsService_Model_Price()); $captureRequest->getCaptureAmount()->setAmount($this->_amount); $captureRequest->getCaptureAmount()->setCurrencyCode($this->getCurrencyCode3($client)); try { $captureResponse = $client->capture($captureRequest); $amazonCaptureId = $captureResponse->getCaptureResult()->getCaptureDetails()->getAmazonCaptureId(); $this->debugLog("
" . var_export($captureRequest, true) . "", __FUNCTION__, 'debug'); $this->debugLog("
" . var_export($captureResponse, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { $msg = $e->getMessage(); $log = "An exception was thrown when trying to capture payment:" . $e->getMessage() . "\n" . $e->getTraceAsString(); while ($e = $e->getPrevious()) { $log .= ("Caused by: " . $e->getMessage() . "\n" . $e->getTraceAsString() . ""); $msg .= "Reason: " . $e->getMessage() . "
" . var_export($refundRequest, true) . "", __FUNCTION__, 'debug'); $this->debugLog("
" . var_export($refundResponse, true) . "", __FUNCTION__, 'debug'); } catch (Exception $e) { $msg = $e->getMessage(); $log = "An exception was thrown when trying to refund payment:" . $e->getMessage() . "\n" . $e->getTraceAsString(); if ($this->_currentMethod->debug) { while ($e = $e->getPrevious()) { $log .= ("Caused by: " . $e->getMessage() . "\n" . $e->getTraceAsString() . ""); $msg .= "Reason: " . $e->getMessage() . "
" . var_export($notificationResponse->amazonData, true) . "", __FUNCTION__, 'debug'); if (!($order_number = $notificationResponse->getReferenceId())) { /* // it is not really an error, orderReferenceNotification do not send a ReferenceId if ($amazonReferenceId=$notificationResponse->getAmazonReferenceId()) { $payments=$this->getDatasByAmazonReferenceId($amazonReferenceId); if (!$payments) { $this->debugLog('no ReferenceId IPN received', $notificationClass, 'error'); } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payments[0]->virtuemart_order_id); $this->storeAmazonInternalData($order, NULL, NULL, $notification, NULL, $notificationResponse->getStoreInternalData()); } */ $this->debugLog('no ReferenceId IPN received', $notificationClass, 'error'); return true; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { $this->debugLog('Received a ' . $notificationClass . ' with order number ' . $order_number . ' but no order in DB with that number', $notificationClass, 'error'); return true; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { // we ignore it because we receive also notification when refund/capture is done in the Amazon BE, and there is no valid reference //$this->debugLog('Received a ' . $newClass . ' with order number ' . $order_number . 'but no order in DB with that number in AMAZON payment table', $newClass, 'error'); return true; } $amazonState = $notificationResponse->onNotificationUpdateOrderHistory($order, $payments); $this->storeAmazonInternalData($order, NULL, NULL, $notification, NULL, $notificationResponse->getStoreInternalData()); $nextOperation = $notificationResponse->onNotificationNextOperation($order, $payments, $amazonState); if ($nextOperation === false) { return; } if (!function_exists($nextOperation)) { //$this->debugLog('Trying to call ' . $nextOperation . ' but the function does not exists: Programming error', $notificationClass, 'error'); } $this->$nextOperation($payments, $order); } private function onNotificationGetAuthorization ($payments, $order) { $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } $this->getAuthorization($client, NULL, $order, false); } private function onNotificationGetAuthorizationDetails ($payments, $order) { $amazonAuthorizationId = $this->getAmazonAuthorizationId($payments); if (!$amazonAuthorizationId) { return false; } $authorizationDetailsResponse = $this->getAuthorizationDetails($amazonAuthorizationId, $order); if (!$authorizationDetailsResponse->isSetGetAuthorizationDetailsResult()) { return; } $getAuthorizationDetailsResult = $authorizationDetailsResponse->getGetAuthorizationDetailsResult(); if (!$getAuthorizationDetailsResult->isSetAuthorizationDetails()) { return; } $getAuthorizationDetails = $getAuthorizationDetailsResult->getAuthorizationDetails(); $this->updateAuthorizeBillingAddressInOrder($getAuthorizationDetails, $order); if ($getAuthorizationDetails->isSetAuthorizationStatus()) { $authorizationStatus = $getAuthorizationDetails->getAuthorizationStatus(); if ($authorizationStatus->isSetState()) { $amazonState = $authorizationStatus->getState(); } if ($authorizationStatus->isSetReasonCode()) { $reasonCode = $authorizationStatus->getReasonCode(); } if ($amazonState == 'Closed') { $this->closeAuthorization($getAuthorizationDetails->getAmazonAuthorizationId(), $order); } } $this->loadHelperClass('amazonHelperGetAuthorizationDetailsResponse'); $amazonHelperGetAuthorizationDetailsResponse = new amazonHelperGetAuthorizationDetailsResponse($authorizationDetailsResponse, $this->_currentMethod); $amazonHelperGetAuthorizationDetailsResponse->onResponseUpdateOrderHistory($order); return; } /** * @param $amazonOrderReferenceId * @param $order */ function closeOrderReference ($amazonOrderReferenceId, $order, $closeReason = 'VMPAYMENT_AMAZON_CLOSE_REASON_ORDER_COMPLETE') { $this->loadAmazonClass('OffAmazonPaymentsService_Model_CloseOrderReferenceRequest'); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $closeOrderReferenceRequest = new OffAmazonPaymentsService_Model_CloseOrderReferenceRequest(); $closeOrderReferenceRequest->setSellerId($this->_currentMethod->sellerId); $closeOrderReferenceRequest->setAmazonOrderReferenceId($amazonOrderReferenceId); $closeOrderReferenceRequest->setClosureReason(vmText::_($closeReason)); $closeOrderReferenceResponse = $client->closeOrderReference($closeOrderReferenceRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return; } $this->loadHelperClass('amazonHelpercloseOrderReferenceResponse'); $amazonHelperCloseOrderReferenceResponse = new amazonHelpercloseOrderReferenceResponse($closeOrderReferenceResponse, $this->_currentMethod); $storeInternalData = $amazonHelperCloseOrderReferenceResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $closeOrderReferenceRequest, $closeOrderReferenceResponse, NULL, NULL, $storeInternalData); return; } /** * To close an authorization after the total amount of the authorization has been captured * @return mixed */ function closeAuthorization ($amazonAuthorizationId, $order, $closeReason = 'VMPAYMENT_AMAZON_CLOSE_REASON_ORDER_COMPLETE') { $this->loadAmazonClass('OffAmazonPaymentsService_Model_CloseAuthorizationRequest'); $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return; } try { $closeAuthorizationRequest = new OffAmazonPaymentsService_Model_CloseAuthorizationRequest(); $closeAuthorizationRequest->setSellerId($this->_currentMethod->sellerId); $closeAuthorizationRequest->setAmazonAuthorizationId($amazonAuthorizationId); $closeAuthorizationRequest->setClosureReason(vmText::_($closeReason)); $closeAuthorizationResponse = $client->closeAuthorization($closeAuthorizationRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return; } $this->loadHelperClass('amazonHelperCloseAuthorizationResponse'); $amazonHelperCloseAutorizationResponse = new amazonHelperCloseAuthorizationResponse($closeAuthorizationResponse, $this->_currentMethod); $storeInternalData = $amazonHelperCloseAutorizationResponse->getStoreInternalData(); $this->storeAmazonInternalData($order, $closeAuthorizationRequest, $closeAuthorizationResponse, NULL, NULL, $storeInternalData); return; } private function isValidNotificationType ($notificationType) { $validNotificationType = array( "OrderReferenceNotification", //"BillingAgreementNotification", "AuthorizationNotification", "CaptureNotification", "RefundNotification", ); if (in_array($notificationType, $validNotificationType)) { $this->debugLog("received notificationType: " . $notificationType, __FUNCTION__, 'debug'); return true; } return false; } private function getWidgetURL () { $region = $this->_currentMethod->region; $region_europe = array('UK', 'DE'); $url = ''; if (in_array($region, $region_europe)) { if ($this->_currentMethod->shop_mode == 'sandbox') { $url = 'https://static-eu.payments-amazon.com/OffAmazonPayments/' . strtolower($region) . '/sandbox/js/Widgets.js'; } else { $url = 'https://static-eu.payments-amazon.com/OffAmazonPayments/' . strtolower($region) . '/js/Widgets.js'; } $url .= '?sellerId=' . $this->_currentMethod->sellerId; } else { if ($this->_currentMethod->environment == 'sandbox') { $url = $this->_currentMethod->sandbox_signin; } else { $url = $this->_currentMethod->production_signin; } } return $url; } private function getAmazonOrderReferenceIdFromPayments ($payments) { foreach ($payments as $payment) { if ($payment->amazon_class_request_type == 'OffAmazonPaymentsService_Model_ConfirmOrderReferenceRequest') { $amazon_request = unserialize($payment->amazon_request); return $amazon_request->AmazonOrderReferenceId; } } } private function incrementRetryInvalidPaymentMethodInSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData['RetryInvalidPaymentMethod'])) { $sessionAmazonData['RetryInvalidPaymentMethod']++; } else { $sessionAmazonData['RetryInvalidPaymentMethod'] = 0; } $session->set('amazon', json_encode($sessionAmazonData), 'vm'); return $sessionAmazonData['RetryInvalidPaymentMethod']; } private function getRetryInvalidPaymentMethodFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData['RetryInvalidPaymentMethod'])) { return $sessionAmazonData['RetryInvalidPaymentMethod']; } else { return 0; } } /** * save the BT and ST in case the shopper has already given one * @param $cart */ private function saveBTandSTInSession ($cart) { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); $sessionAmazonData = json_decode($sessionAmazon, true); // check if it is already saved or not if (!isset($sessionAmazonData['BT'])) { $sessionAmazonData['BT'] = $cart->BT; $sessionAmazonData['ST'] = $cart->ST; $session->set('amazon', json_encode($sessionAmazonData), 'vm'); } } private function getBTandSTFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); $address['BT'] = NULL; $address['ST'] = NULL; if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData['BT']) OR isset($sessionAmazonData['ST'])) { $address['BT'] = $sessionAmazonData['BT']; $address['ST'] = $sessionAmazonData['ST']; } } return $address; } /** * @return null */ private function getAmazonOrderReferenceIdWeightFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id])) { return $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]; } } return NULL; } /** * @return null */ private function clearAmazonSession () { $session = JFactory::getSession(); $session->clear('amazon', 'vm'); return NULL; } /** * @return null */ private function getAmazonSalesPriceFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]) and isset($sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['_salesPrices']) ) { return $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['_salesPrices']; } } return NULL; } /** * @param $salesPrices */ private function setSalesPriceInSession ($salesPrices) { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); } else { $sessionAmazonData = array(); } $sessionAmazonData['virtuemart_paymentmethod_id'] = $this->_currentMethod->virtuemart_paymentmethod_id; $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['_salesPrices'] = $salesPrices; $session->set('amazon', json_encode($sessionAmazonData), 'vm'); } /** * @return null */ private function getAmazonOrderReferenceIdFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id])) { return $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['_amazonOrderReferenceId']; } } return NULL; } /** * @return null */ private function getisOnlyDigitalGoodsFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); if (isset($sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id])) { return $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['isOnlyDigitalGoods']; } } return NULL; } /** * @param $amazonOrderReferenceId * @param $isOnlyDigitalGoods */ private function setAmazonOrderReferenceIdInSession ($amazonOrderReferenceId, $isOnlyDigitalGoods) { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); } else { $sessionAmazonData = array(); } $sessionAmazonData['virtuemart_paymentmethod_id'] = $this->_currentMethod->virtuemart_paymentmethod_id; $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['_amazonOrderReferenceId'] = $amazonOrderReferenceId; $sessionAmazonData[$this->_currentMethod->virtuemart_paymentmethod_id]['isOnlyDigitalGoods'] = $isOnlyDigitalGoods; $session->set('amazon', json_encode($sessionAmazonData), 'vm'); } /** * Use the order reference object to query the order information, including * the current physical delivery address as selected by the buyer * * @return OffAmazonPaymentsService_Model_GetOrderReferenceDetailsResponse service response */ private function getOrderReferenceDetailsResponse ($addressConsentToken = null) { $this->loadAmazonClass('OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_GetOrderReferenceDetailsResponse'); $this->loadAmazonClass('OffAmazonPaymentsService_Model_OrderReferenceDetails'); //$_amazonOrderReferenceId = $this->getAmazonOrderReferenceId(); if (empty($this->_amazonOrderReferenceId)) { vmError('VMPAYMENT_AMAZON_LOGIN'); return FALSE; } $client = $this->getOffAmazonPaymentsService_Client(); if ($client == NULL) { return NULL; } try { $getOrderReferenceDetailsRequest = new OffAmazonPaymentsService_Model_GetOrderReferenceDetailsRequest(); $getOrderReferenceDetailsRequest->setSellerId($this->_currentMethod->sellerId); $getOrderReferenceDetailsRequest->setAmazonOrderReferenceId($this->_amazonOrderReferenceId); if (is_null($addressConsentToken) == FALSE) { $decodedToken = urldecode($addressConsentToken); $getOrderReferenceDetailsRequest->setAddressConsentToken($decodedToken); } $orderReferenceDetailsResponse = $client->getOrderReferenceDetails($getOrderReferenceDetailsRequest); } catch (Exception $e) { $this->amazonError(__FUNCTION__ . ' ' . $e->getMessage(), $e->getCode()); return FALSE; } $this->debugLog($orderReferenceDetailsResponse, 'getOrderReferenceDetailsResponse', 'debug'); return $orderReferenceDetailsResponse; } private function isValidUpdateOrderStatus ($orderStatus) { $validOrderStatus = array( $this->_currentMethod->status_capture, $this->_currentMethod->status_refunded, $this->_currentMethod->status_cancel, ); if (!in_array($orderStatus, $validOrderStatus)) { return false; } return true; } /** * @return bool */ private function isCaptureImmediate ($cart) { if ($cart) { return ($this->_currentMethod->capture_mode == "capture_immediate" OR $this->isSomeDigitalGoods($cart)); } else { return false; } } private function isERPModeEnabled () { if ($this->_currentMethod->erp_mode == "erp_mode_enabled") { return true; } else { return false; } } private function isAuthorizationDoneByErp () { if ($this->_currentMethod->authorization_mode_erp_enabled == "authorization_done_by_erp") { return true; } else { return false; } } /** * in case of only Digital Goods, the Address Wallet is not displayed * @param $cart * @return bool */ private function isOnlyDigitalGoods ($cart) { if (!$this->_currentMethod->digital_goods) { return false; } if ($cart) { $weight = $this->getOrderWeight($cart, 'GR'); } else { $weight = $this->getisOnlyDigitalGoodsFromSession(); } if ($weight == 0) { return true; } else { return false; } } /** * In case of some Digital goods, the capture is immediate * @param $cart * @return bool */ private function isSomeDigitalGoods ($cart) { if (!$this->_currentMethod->digital_goods) { return false; } foreach ($cart->products as $product) { if ($product->product_weight == 0) { return true; } } return false; } /** * in VM, the payment is not showed if the buyer browse in another language * @return bool */ private function isValidLanguage () { if (!$this->_currentMethod->language_restriction) { return true; } $lang = JFactory::getLanguage(); $tag = strtolower(substr($lang->get('tag'), 0, 2)); if (array_key_exists($tag, $this->languages_region) AND $this->languages_region[$tag] == $this->_currentMethod->region) { return true; } return false; } /** * @return bool */ private function isValidAmount ($amount) { $this->_currentMethod->min_amount = (float)str_replace(',', '.', $this->_currentMethod->min_amount); $this->_currentMethod->max_amount = (float)str_replace(',', '.', $this->_currentMethod->max_amount); $amount_cond = ($amount > 0 AND $amount >= $this->_currentMethod->min_amount AND $amount <= $this->_currentMethod->max_amount OR ($this->_currentMethod->min_amount <= $amount AND ($this->_currentMethod->max_amount == 0))); if ($amount == 0 or !$amount_cond) { vmdebug('AMAZON checkConditions $amount_cond false'); return false; } return true; } /** * Exclusion of unsupported items: product categories as “not available via Amazon Payments”. * @param $cart * @return bool */ private function isValidProductCategories ($cart) { if (!is_array($this->_currentMethod->exclude_categories)) { $exclude_categories[0] = $this->_currentMethod->exclude_categories; } else { $exclude_categories = $this->_currentMethod->exclude_categories; } foreach ($cart->products as $product) { if (array_intersect($exclude_categories, $product->categories)) { return false; } } return true; } // // Session functions // private function getDataFromSession () { $session = JFactory::getSession(); $sessionAmazon = $session->get('amazon', 0, 'vm'); if ($sessionAmazon) { $sessionAmazonData = json_decode($sessionAmazon, true); return $sessionAmazonData; } return false; } // // DEBUG AND LOG FUNCTIONS // /** * @param string $message * @param string $title * @param string $type * @param bool $echo * @param bool $doVmDebug */ function debugLog ($message, $title = '', $type = 'message', $echo = false, $doVmDebug = false) { if ($this->_currentMethod->debug) { $this->debug($message, $title, true); } if ($echo) { echo $message . '
'; if (is_array($subject)) { $debug .= str_replace("=>", "⇒", str_replace("Array", "Array", nl2br(str_replace(" ", " ", print_r($subject, true))))); } else { //$debug .= str_replace("=>", "⇒", str_replace("Array", "Array", (str_replace(" ", " ", print_r($subject, true))))); $debug .= str_replace("=>", "⇒", str_replace("Array", "Array", print_r($subject, true))); } //$debug .= ''; $debug .= '
" . var_export($_SERVER, true) . "", __FUNCTION__, 'debug'); $headers = ''; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value; } } //$this->debugLog("getallheaders Local function returns" . "
" . var_export($headers, true) . "", __FUNCTION__, 'debug'); return $headers; } else { return getallheaders(); } } } // No closing tag