%PDF- %PDF-
| Direktori : /home1/lightco1/public_html/plugins/vmpayment/amazon/ |
| Current File : //home1/lightco1/public_html/plugins/vmpayment/amazon/amazon.php |
<?php
defined('_JEXEC') or die('Direct Access to ' . basename(__FILE__) . 'is not allowed.');
/**
*
* @package VirtueMart
* @subpackage vmpayment
* @version $Id: amazon.php 8585 2014-11-25 11:11:13Z alatak $
* @author Valérie Isaksen
* @link http://www.virtuemart.net
* @copyright Copyright (c) 2004 - November 10 2015 VirtueMart Team. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
*
*/
if (!class_exists('VmConfig')) {
require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
}
if (!class_exists('vmPSPlugin')) {
require(JPATH_VM_PLUGINS . DS . 'vmpsplugin.php');
}
/**
* Class plgVmpaymentAmazon
* payments.amazon.co.uk
* payments.amazon.de
* https://sellercentral.amazon.co.uk
*/
class plgVmpaymentAmazon extends vmPSPlugin {
// instance of class
static $widgetScriptLoaded = false;
var $_amazonOrderReferenceId = NULL;
const AMAZON_EMPTY_USER_FIELD = "amazon";
const AMAZON_EMPTY_USER_FIELD_EMAIL = "dummy@domain.com";
const AUTHORIZE_TRANSACTION_TIMEOUT = 60;
var $_currentMethod = NULL;
private $_amount = 0.0;
private $_is_digital = false;
private $_order_number = NULL;
var $languages_region = array(
'en' => '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) {
$display = '';
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;
}
if (!class_exists('ShopFunctions'))
require(VMPATH_ADMIN . DS . 'helpers' . DS . 'shopfunctions.php');
$clientIp= ShopFunctions::getClientIP();
$ip_whitelist = explode(";", $this->_currentMethod->ip_whitelist);
if (in_array($clientIp, $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'] = '3.0.12';
$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("<pre>" . var_export($payments, true) . "</pre>", __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 '<dl id="system-message"><dt class="error">Error</dt><dd class="error message"><ul><li>' . $msg . '</li></ul></dd></dl>';
}
/**
* @param VirtueMartCart $cart
*/
public function plgVmOnCheckoutCheckDataPayment (VirtueMartCart $cart) {
static $checkoutCheckDataPaymentDone = false;
if (!$this->selectedThisByMethodId($cart->virtuemart_paymentmethod_id)) {
/*
if ($cart->layout==$this->_name) {
if (!class_exists('VmConfig')) {
require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
}
VmConfig::loadConfig();
$cart->layout = VmConfig::get('cartlayout', 'default');
$cart->setCartIntoSession();
}
*/
return NULL; // Another method was selected, do nothing
}
if (!($this->_currentMethod = $this->getVmPluginMethod($cart->virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
$this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession();
if (empty($this->_amazonOrderReferenceId)) {
//$message = vmText::_('VMPAYMENT_AMAZON_PAYWITHAMAZON_BUTTON');
//vmError($message, $message);
return false;
}
if ($checkoutCheckDataPaymentDone) {
return true;
}
$client = $this->getOffAmazonPaymentsService_Client();
if ($client==NULL) return;
// incase the Address was not displayed
if ($this->isOnlyDigitalGoods($cart)) {
return true;
}
$physicalDestination = $this->getPhysicalDestination();
if (!$physicalDestination) {
// may be we have just logged in, so there is no physical destination
//$this->leaveAmazonCheckout();
return false;
}
$update_data = $this->getUserInfoFromAmazon($physicalDestination);
if (!$this->isValidCountry($update_data['virtuemart_country_id'])) {
$country = shopFunctions::getCountryByID($update_data['virtuemart_country_id']);
$app = JFactory::getApplication();
$leaveAmazonCheckoutLink = $this->getLeaveAmazonCheckoutLink();
//$app->enqueueMessage(vmText::sprintf('VMPAYMENT_AMAZON_UPDATECART_DELIVERYCOUNTRYNOTALLOWED', $country, $leaveAmazonCheckoutLink));
$app->enqueueMessage(vmText::sprintf('VMPAYMENT_AMAZON_UPDATECART_DELIVERYCOUNTRYNOTALLOWED', $country));
//$this->leaveAmazonCheckout();
return false;
}
// setOrderReferenceDetails
if (!$setOrderReferenceDetailsResponse = $this->setOrderReferenceDetails($client, $cart)) {
$this->leaveAmazonCheckout();
$this->onErrorRedirectToCart();
return FALSE;
}
// getOrderReferenceDetails
if (!$getOrderReferenceDetailsResponse = $this->getOrderReferenceDetails($client)) {
$this->removeAmazonAddressFromCart($cart);
$this->clearAmazonSession();
$cart->emptyCart();
$this->onErrorRedirectToCart();
return FALSE;
}
$orderReferenceDetails = $getOrderReferenceDetailsResponse->GetOrderReferenceDetailsResult->getOrderReferenceDetails();
if ($this->isSetConstraints($cart, $orderReferenceDetails)) {
return false;
}
$checkoutCheckDataPaymentDone = true;
return true;
}
private function getLeaveAmazonCheckoutLink () {
$leaveAmazonCheckoutLink = '<a href="#" class="leaveAmazonCheckout">' . vmText::_('VMPAYMENT_AMAZON_LEAVE_PAY_WITH_AMAZON') . '</a>';
return $leaveAmazonCheckoutLink;
}
/**
* Constraints indicates if mandatory information is missing or incorrect in the Order Reference Object
* @param $cart
* @param $orderReferenceDetails
* @return bool
*/
private function isSetConstraints ($cart, $orderReferenceDetails) {
if ($orderReferenceDetails->isSetConstraints()) {
$constraints = $orderReferenceDetails->getConstraints();
$constraintList = $constraints->getConstraint();
foreach ($constraintList as $constraint) {
if ($constraint->isSetDescription()) {
$this->setInConfirmOrder($cart, false);
switch ($constraint->isSetConstraintID($constraint)) {
case 'ShippingAddressNotSet':
$this->handleShippingAddressNotSetConstraint($constraint);
break;
case 'PaymentPlanNotSet':
$this->handlePaymentPlanNotSetConstraint($constraint);
break;
case 'AmountNotSet':
//$this->handleAmountNotSetConstraint($constraint);
// PROGRAMMING ERRROR TODO
break;
case 'PaymentMethodNotAllowed':
$this->handlePaymentMethodNotAllowedConstraint($constraint);
break;
default:
vmError('VMPAYMENT_AMAZON_CONSTRAINTID_UNKOWN');
$this->onErrorRedirectToCart();
return true;
}
return true;
}
}
}
return false;
}
/**
* Display again the Amazon AddressBook widget to the buyer to collect shipping Information
* @param $constraint
*/
private function handleShippingAddressNotSetConstraint ($constraint) {
$this->renderAddressbookWallet();
}
/**
* Display again the Amazon Wallet widget to the buyer to collect payment Information
* @param $constraint
*/
private function handlePaymentPlanNotSetConstraint ($constraint) {
$this->renderAddressbookWallet();
}
/**
* Call again the SetOrderReferenceDetails operation with the order amount
* This constraint should not happen. It is a programming error
* @param $constraint
*/
private function handleAmountNotSetConstraint ($constraint) {
$this->amazonError('handleAmountNotSetConstraint: ' . $constraint->getDescription());
}
/**
* Display again the Amazon Wallet widget and Request the buyer to select a different payment method
* @param $constraint
*/
private function handlePaymentMethodNotAllowedConstraint ($constraint) {
$this->debugLog("<pre>" . var_export($constraint, true) . "</pre>", __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;
}
$this->_amount = $order['details']['BT']->order_total;
$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("<pre>" . var_export($BTFromAmazon, true) . "</pre>", __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->emptyCache();
$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("<pre>" . var_export($ST, true) . "</pre>", __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("<pre>" . var_export($setOrderReferenceDetailsRequest, true) . "</pre>", __FUNCTION__, 'debug');
$this->debugLog("<pre>" . var_export($setOrderReferenceDetailsResponse, true) . "</pre>", __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("<pre>" . var_export($getOrderReferenceDetailsRequest, true) . "</pre>", __FUNCTION__, 'debug');
$this->debugLog("<pre>" . var_export($getOrderReferenceDetailsResponse, true) . "</pre>", __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("<pre>" . var_export($confirmOrderReferenceRequest, true) . "</pre>", __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("<pre>" . var_export($confirmOrderReferenceResponse, true) . "</pre>", __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());
$authorizeRequest->getAuthorizationAmount()->setAmount($this->getTotalInPaymentCurrency($client, $this->_amount, $this->getCurrencyId($client)));
$authorizeRequest->getAuthorizationAmount()->setCurrencyCode($this->getCurrencyCode3($client));
try {
$authorizeResponse = $client->authorize($authorizeRequest);
$amazonAuthorizationId = $authorizeResponse->getAuthorizeResult()->getAuthorizationDetails()->getAmazonAuthorizationId();
//$this->debugLog("ERREUR<pre>" . var_export($authorizeRequest, true) . "</pre>", __FUNCTION__, 'debug');
//$this->debugLog("ERREUR<pre>" . var_export($authorizeResponse, true) . "</pre>", __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 = $order['details']['BT']->order_total;
$this->_order_number = $this->getUniqueReferenceId($order['details']['BT']->order_number);
$html = $this->vmConfirmedOrder(NULL, $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 = $orderModelData['details']['BT']->order_total;
$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) {
// todo
return true;
}
/**
* @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;
}
}
private function cancelPayment ($payments, $order) {
}
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->getTotalInPaymentCurrency($client, $this->_amount, $order['details']['BT']->order_currency));
$captureRequest->getCaptureAmount()->setCurrencyCode($this->getCurrencyCode3($client));
try {
$captureResponse = $client->capture($captureRequest);
$amazonCaptureId = $captureResponse->getCaptureResult()->getCaptureDetails()->getAmazonCaptureId();
$this->debugLog("<pre>" . var_export($captureRequest, true) . "</pre>", __FUNCTION__, 'debug');
$this->debugLog("<pre>" . var_export($captureResponse, true) . "</pre>", __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() . "<br />";
$log .= "\n";
}
$this->debugLog($log, __FUNCTION__, 'debug');
$this->amazonError(__FUNCTION__ . ' ' . $msg);
return false;
}
$this->loadHelperClass('amazonHelperCaptureResponse');
$amazonHelperCaptureResponse = new amazonHelperCaptureResponse($captureResponse, $this->_currentMethod);
$amazonHelperCaptureResponse->onResponseUpdateOrderHistory($order);
//$orderModel = VmModel::getModel('orders');
//$orderModel->updateStatusForOneOrder($order['details']['BT']->virtuemart_order_id, $order_history, TRUE);
$storeInternalData = $amazonHelperCaptureResponse->getStoreInternalData();
$this->storeAmazonInternalData($order, $captureRequest, $captureResponse, NULL, $this->renderPluginName($this->_currentMethod), $storeInternalData, NULL, $this->_amount);
return $amazonCaptureId;
}
private function refundPayment ($payments, $order) {
$amazonCaptureId = $this->getAmazonCaptureId($payments);
if (empty($amazonCaptureId)) {
vmError(vmText::_('VMPAYMENT_AMAZON_UPDATEPAYMENT_NOAMAZONCAPTUREID'));
return false;
}
$this->loadAmazonClass('OffAmazonPaymentsService_Model_RefundRequest');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_Price');
$client = $this->getOffAmazonPaymentsService_Client();
if ($client==NULL) return;
$refund = new OffAmazonPaymentsService_Model_Price();
$refund->setCurrencyCode($this->getCurrencyCode3($client));
$refund->setAmount($this->getTotalInPaymentCurrency($client, $this->_amount, $order['details']['BT']->order_currency));
$refundRequest = new OffAmazonPaymentsService_Model_RefundRequest();
$refundRequest->setSellerId($this->_currentMethod->sellerId);
$refundRequest->setAmazonCaptureId($amazonCaptureId);
$refundRequest->setRefundReferenceId($this->getUniqueReferenceId($order['details']['BT']->order_number)); // random string
$refundRequest->setRefundAmount($refund);
try {
$refundResponse = $client->refund($refundRequest);
$amazonRefundId = $refundResponse->getRefundResult()->getRefundDetails()->getAmazonRefundId();
$this->debugLog("<pre>" . var_export($refundRequest, true) . "</pre>", __FUNCTION__, 'debug');
$this->debugLog("<pre>" . var_export($refundResponse, true) . "</pre>", __FUNCTION__, 'debug');
} catch (Exception $e) {
$msg = $e->getMessage();
$log = "An exception was thrown when trying to refund payment:" . $e->getMessage() . "\n" . $e->getTraceAsString();
while ($e = $e->getPrevious()) {
$log .= ("Caused by: " . $e->getMessage() . "\n" . $e->getTraceAsString() . "");
$msg .= "Reason: " . $e->getMessage() . "<br />";
$log .= "\n";
}
$this->debugLog($log, __FUNCTION__, 'debug');
vmError(__FUNCTION__ . ' ' . $msg);
return false;
}
$this->loadHelperClass('amazonHelperRefundResponse');
$amazonHelperRefundResponse = new amazonHelperRefundResponse($refundResponse, $this->_currentMethod);
$storeInternalData = $amazonHelperRefundResponse->getStoreInternalData();
$this->storeAmazonInternalData($order, $refundRequest, $refundResponse, NULL, $this->renderPluginName($this->_currentMethod), $storeInternalData, NULL, $refund);
return $amazonRefundId;
}
function getOrderReferenceState () {
$client = $this->getOffAmazonPaymentsService_Client();
if ($client==NULL) return false;
$getOrderReferenceDetailsResponse = $this->getOrderReferenceDetails($client);
if ($getOrderReferenceDetailsResponse) {
return $getOrderReferenceDetailsResponse->getGetOrderReferenceDetailsResult()->getOrderReferenceDetails()->getOrderReferenceStatus()->getState();
}
return false;
}
/**
* Capture reference Id must always be unique
* @param $order_number
* @return string
*/
private function getUniqueReferenceId ($order_number) {
return $order_number . '-' . time();
}
function getAuthorizationResponse ($payments) {
// we don't care, may be he has change his payment config
/*
if($this->_currentMethod->capture_mode=='immediate_capture') {
vmError(vmText::_('VMPAYMENT_AMAZON_UPDATEPAYMENT_CAPTUREMODE_IMMEDIATE'));
return false;
}
*/
foreach ($payments as $payment) {
if ($payment->amazon_class_response_type == 'OffAmazonPaymentsService_Model_AuthorizeResponse' or $payment->amazon_class_response_type == 'OffAmazonPaymentsNotifications_Model_authorizationNotification') {
return $payment;
}
}
vmError(vmText::_('VMPAYMENT_AMAZON_UPDATEPAYMENT_NOAMAZONAUTHORIZATIONID'));
return false;
}
/**
* if amount = 0 then it is a full capture
* otherwise it is a partial capture
* in this case if a capture has already been done, a new authorization for that amount is requested
*/
function getAmazonAuthorizationId ($payments) {
$payments_reverse = array_reverse($payments);
foreach ($payments_reverse as $payment) {
if (!empty($payment->amazon_response_amazonAuthorizationId)) {
return $payment->amazon_response_amazonAuthorizationId;
}
}
return NULL;
}
/**
* @param $payments
* @return null
*/
function getAmazonCaptureId ($payments) {
$this->loadAmazonServicesClasses();
$this->loadAmazonNotificationClasses();
$payments_reverse = array_reverse($payments);
foreach ($payments_reverse as $payment) {
if (!empty($payment->amazon_response_amazonCaptureId)) {
return $payment->amazon_response_amazonCaptureId;
}
}
return NULL;
}
/**
* @param $virtuemart_paymentmethod_id
* @param $paymentCurrencyId
* @return bool
*/
function plgVmgetPaymentCurrency ($virtuemart_paymentmethod_id, &$paymentCurrencyId) {
if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
if (!$this->selectedThisElement($method->payment_element)) {
return FALSE;
}
$client = $this->getOffAmazonPaymentsService_Client();
if ($client==NULL) return;
$method->payment_currency = $this->getCurrencyId($client);
$paymentCurrencyId = $method->payment_currency;
return TRUE;
}
/**
* @param $html
* @return bool|null
*/
function plgVmOnPaymentResponseReceived (&$html) {
$this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php');
if (!class_exists('shopFunctionsF')) {
require(JPATH_VM_SITE . DS . 'helpers' . DS . 'shopfunctionsf.php');
}
$this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
VmConfig::loadJLang('com_virtuemart_orders', TRUE);
$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 NULL;
}
$html = "We will send you an email confirmation with your order details shortly";
$html .= "Our order number";
$html .= "Amazon Reference";
$html .= "Go tot payments.amazon... to see your payment history and other account information.";
vRequest::setVar('display_title', false);
vRequest::setVar('html', $html);
return true;
}
function plgVmOnUserPaymentCancel () {
$this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
$order_number = vRequest::getUword('on');
if (!$order_number) {
return FALSE;
}
if (!$virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number)) {
return NULL;
}
if (!($paymentTable = $this->getDataByOrderId($virtuemart_order_id))) {
return NULL;
}
$session = JFactory::getSession();
$return_context = $session->getId();
$field = $this->_name . '_custom';
if (strcmp($paymentTable->$field, $return_context) === 0) {
$this->handlePaymentUserCancel($virtuemart_order_id);
}
return TRUE;
}
/**
* Display stored payment data for an order
*
* @see components/com_virtuemart/helpers/vmPSPlugin::plgVmOnShowOrderBEPayment()
*/
function plgVmOnShowOrderBEPayment ($virtuemart_order_id, $virtuemart_paymentmethod_id) {
if (!$this->selectedThisByMethodId($virtuemart_paymentmethod_id)) {
return NULL; // Another method was selected, do nothing
}
if (!($this->_currentMethod = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
$payments= $this->getDatasByOrderId($virtuemart_order_id);
$html = '<table class="adminlist table" >' . "\n";
$html .= $this->getHtmlHeaderBE();
$html .= $this->showActionOrderBEPayment($virtuemart_order_id, $virtuemart_paymentmethod_id, $payments);
$html .= $this->showOrderBEPayment($virtuemart_order_id, $payments);
$html .= '</table>' . "\n";
return $html;
}
private function showActionOrderBEPayment ($virtuemart_order_id, $virtuemart_paymentmethod_id, $payments) {
//return;
$this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
$orderModel = VmModel::getModel('orders');
$order = $orderModel->getOrder($virtuemart_order_id);
$options = array();
$options[] = JHTML::_('select.option', 'capturePayment', JText::_('VMPAYMENT_AMAZON_ORDER_BE_CAPTURE'), 'value', 'text');
$options[] = JHTML::_('select.option', 'refundPayment', JText::_('VMPAYMENT_AMAZON_ORDER_BE_REFUND'), 'value', 'text');
$options[] = JHTML::_('select.option', 'newAuthorization', JText::_('VMPAYMENT_AMAZON_ORDER_BE_NEW_AUTHORIZATION'), 'value', 'text');
$actionList = JHTML::_('select.genericlist', $options, 'action', '', 'value', 'text', 'capturePayment', 'action', true);
//$html = '<table class="adminlist table-striped" >' . "\n";
$html = '';
$html .= '<form action="index.php" method="post" name="updateOrderBEPayment" id="updateOrderBEPayment">';
$html .= '<tr ><td >';
$html .= $actionList;
$html .= ' </td><td>';
$html .= '<input type="text" id="amount" name="amount" size="20" value="" class="required" maxlength="25" placeholder="' . vmText::sprintf('VMPAYMENT_AMAZON_ORDER_BE_AMOUNT', shopFunctions::getCurrencyByID($payments[0]->payment_currency, 'currency_code_3')) . '"/>';
$html .= '<input type="hidden" name="type" value="vmpayment"/>';
$html .= '<input type="hidden" name="name" value="amazon"/>';
$html .= '<input type="hidden" name="view" value="plugin"/>';
$html .= '<input type="hidden" name="option" value="com_virtuemart"/>';
$html .= '<input type="hidden" name="virtuemart_order_id" value="' . $virtuemart_order_id . '"/>';
$html .= '<input type="hidden" name="virtuemart_paymentmethod_id" value="' . $virtuemart_paymentmethod_id . '"/>';
$html .= '<span class="icon-nofloat vmicon vmicon-16-save"></span>';
$html .= '<a class="updateOrderBEPayment" href="#" >' . Jtext::_('COM_VIRTUEMART_SAVE') . '</a>';
$html .= '</form>';
$html .= ' </td></tr>';
$doc = JFactory::getDocument();
$doc->addScriptDeclaration("
//<![CDATA[
jQuery(document).ready( function($) {
/*
jQuery('#action').change(function() {
if ($('#action').val()=='authorizationNew') {
$('#amount').hide();
} else {
$('#amount').show();
}
});
*/
jQuery('.updateOrderBEPayment').click(function() {
document.updateOrderBEPayment.submit();
return false;
});
});
//]]>
");
//$html .= '</table>' ;
return $html;
}
private function showOrderBEPayment ($virtuemart_order_id, $payments) {
$db = JFactory::getDBO();
$query = 'SHOW COLUMNS FROM `' . $this->_tablename . '` ';
$db->setQuery($query);
$columns = $db->loadColumn(0);
$html = '';
$first = TRUE;
$lang = JFactory::getLanguage();
foreach ($payments as $payment) {
if ($payment->amazon_class_request_type) {
$this->loadAmazonClass($payment->amazon_class_request_type);
}
if ($payment->amazon_class_response_type) {
$this->loadAmazonClass($payment->amazon_class_response_type);
}
if ($payment->amazon_class_notification_type) {
$this->loadAmazonClass($payment->amazon_class_notification_type);
}
$html .= '<tr class="row1"><td><strong>' . vmText::_('VMPAYMENT_AMAZON_DATE') . '</strong></td><td align="left"><strong>' . $payment->created_on . '</strong></td></tr>';
// Now only the first entry has this data when creating the order
if ($first) {
$html .= $this->getHtmlRowBE('AMAZON_PAYMENT_NAME', $payment->payment_name);
// keep that test to have it backwards compatible. Old version was deleting that column when receiving an IPN notification
if ($payment->payment_order_total and $payment->payment_order_total != 0.00) {
$html .= $this->getHtmlRowBE('COM_VIRTUEMART_TOTAL', ($payment->payment_order_total * 0.01) . " " . shopFunctions::getCurrencyByID($payment->payment_currency, 'currency_code_3'));
}
if ($payment->email_currency and $payment->email_currency != 0) {
//$html .= $this->getHtmlRowBE($this->_name.'_PAYMENT_EMAIL_CURRENCY', shopFunctions::getCurrencyByID($payment->email_currency, 'currency_code_3'));
}
$first = FALSE;
} else {
$amazon_classes = array();
/*
if (!empty($payment->amazon_request)) {
$amazon_data = unserialize($payment->amazon_request);
$amazon_classes[get_class($amazon_data)] = $payment->amazon_request;
}
*/
$this->loadAmazonServicesClasses();
$this->loadAmazonNotificationClasses();
if (!empty($payment->amazon_request)) {
$amazon_classes[$payment->amazon_class_request_type] = $payment->amazon_request;
$vmClass = $this->getVmClass($payment->amazon_class_request_type);
$html .= $this->getHtmlRowBE(vmText::_('VMPAYMENT_AMAZON_REQUEST_TYPE'), vmText::_('VMPAYMENT_AMAZON_REQUEST_TYPE_' . $vmClass));
$transactionLogContent = $this->getTransactionLogContent($payment->amazon_class_request_type, $payment->amazon_request, $payment);
if (empty($transactionLogContent)) {
vmError("getTransactionLogContent" . $payment->amazon_class_request_type . ' ');
vmError("getTransactionLogContent" . $payment->amazon_request . ' ');
}
$html .= $transactionLogContent;
}
if (!empty($payment->amazon_response)) {
$vmClass = $this->getVmClass($payment->amazon_class_response_type);
$amazon_classes[$payment->amazon_class_response_type] = $payment->amazon_response;
$html .= $this->getHtmlRowBE(vmText::_('VMPAYMENT_AMAZON_RESPONSE_TYPE'), vmText::_('VMPAYMENT_AMAZON_RESPONSE_TYPE_' . $vmClass));
$html .= $this->getResponseData($payment);
$html .= $this->getTransactionLogContent($payment->amazon_class_response_type, $payment->amazon_response, $payment);
} elseif (!empty($payment->amazon_notification)) {
$amazon_classes[$payment->amazon_class_notification_type] = $payment->amazon_notification;
$vmClass = $this->getVmClass($payment->amazon_class_notification_type);
$html .= $this->getHtmlRowBE(vmText::_('VMPAYMENT_AMAZON_NOTIFICATION_TYPE'), vmText::_('VMPAYMENT_AMAZON_NOTIFICATION_TYPE_' . $vmClass));
$html .= $this->getResponseData($payment);
$html .= $this->getTransactionLogContent($payment->amazon_class_notification_type, $payment->amazon_notification, $payment);
}
}
}
$doc = JFactory::getDocument();
$js = "
jQuery().ready(function($) {
$('.amazonLogOpener').click(function() {
var logId = $(this).attr('rel');
$('#amazonLog_'+logId).toggle();
return false;
});
$('.amazonDetailsOpener').click(function() {
var detailsId = $(this).attr('rel');
$('#amazonDetails_'+detailsId).toggle();
return false;
});
});";
$doc->addScriptDeclaration($js);
return $html;
}
function getResponseData ($payment) {
$html = '';
$code = 'amazon_response_';
foreach ($payment as $key => $value) {
// only displays if there is a value or the value is different from 0.00 and the value
if ($value) {
if (substr($key, 0, strlen($code)) == $code) {
$html .= $this->getHtmlRowBE($key, $value);
}
}
}
return $html;
}
function getTransactionLogContent ($amazon_class, $amazon_data_serialized, $payment) {
$html = '';
$this->loadAmazonClass($amazon_class);
$vmClass = $this->getVmClass($amazon_class);
$vmClassName = 'amazonHelper' . $vmClass;
$amazon_data = unserialize($amazon_data_serialized);
$this->loadHelperClass($vmClassName);
$html .= '<tr><td>';
if (!class_exists($vmClassName)) {
vmError(__FUNCTION__ . ' Programming error: class name does not exist:' . $vmClassName);
return NULL;
} elseif (empty($vmClass)) {
vmError(__FUNCTION__ . ' Programming error: class does not exist:' . $vmClass);
return NULL;
} else {
$obj = new $vmClassName($amazon_data, $this->_currentMethod);
$contents = $obj->getContents();
if (!empty($contents)) {
$html .= '<a href="#" class="amazonDetailsOpener" rel="' . $payment->id . $vmClass . '">';
//$html .= '<div style="background-color: white; z-index: 100; right:0; display: none; border:solid 2px; padding:10px;" class="vm-absolute" id="amazonDetails_' . $payment->id . '">';
//$html .= ' </div>';
$html .= ' <span class="icon-nofloat vmicon vmicon-16-xml"></span> ';
$html .= vmText::_('VMPAYMENT_AMAZON_VIEW_TRANSACTION_DETAILS');
$html .= ' </a>';
$html .= '<div style="display:none;" id="amazonDetails_' . $payment->id . $vmClass . '">';
$html .= $contents;
$html .= ' </div>';
}
}
$html .= ' </td>';
$html .= ' <td>';
if ($this->_currentMethod->debug) {
//$html .= '<tr><td></td><td>' . $amazon_class . '
$html .= '<td>' . '
<a href="#" class="amazonLogOpener" rel="' . $payment->id . $vmClass . '" >
<div style="background-color: white; z-index: 100; right:0; display: none; border:solid 2px; padding:10px;" class="vm-absolute" id="amazonLog_' . $payment->id . $vmClass . '">';
$html .= "<pre>" . var_export($amazon_data, true) . "</pre>";
//$html .= $obj->getContents();
$html .= ' </div>
<span class="icon-nofloat vmicon vmicon-16-xml"></span> ';
$html .= vmText::_('VMPAYMENT_AMAZON_VIEW_TRANSACTION_LOG');
$html .= ' </a>';
}
$html .= ' </td></tr>';
//}
return $html;
}
function getVmClass ($amazonClass) {
$pos = strrpos($amazonClass, '_');
$vmClass = substr($amazonClass, $pos + 1);
return $vmClass;
}
/**
* Create the table for this plugin if it does not yet exist.
* This functions checks if the called plugin is active one.
* When yes it is calling the standard method to create the tables
*
* @author Valérie Isaksen
*
*/
public function plgVmOnStoreInstallPaymentPluginTable ($jplugin_id) {
if ($res = $this->selectedThisByJPluginId($jplugin_id)) {
$virtuemart_paymentmethod_id = vRequest::getInt('virtuemart_paymentmethod_id');
$method = $this->getPluginMethod($virtuemart_paymentmethod_id);
vmdebug('plgVmOnStoreInstallPaymentPluginTable', $method, $virtuemart_paymentmethod_id);
if (!extension_loaded('curl')) {
vmError(vmText::sprintf('VMPAYMENT_AMAZON_CONF_MANDATORY_PHP_EXTENSION', 'curl'));
}
if (!extension_loaded('openssl')) {
vmError(vmText::sprintf('VMPAYMENT_AMAZON_CONF_MANDATORY_PHP_EXTENSION', 'openssl'));
}
}
return $this->onStoreInstallPluginTable($jplugin_id);
}
/**
* This event is fired after the payment method has been selected. It can be used to store
* additional payment info in the cart.
*
* @author Valérie isaksen
*
* @param VirtueMartCart $cart : the actual cart
* @return null if the payment was not selected, true if the data is valid, error message if the data is not vlaid
*
*/
public function plgVmOnSelectCheckPayment (VirtueMartCart $cart, &$msg) {
if (!$this->selectedThisByMethodId($cart->virtuemart_paymentmethod_id)) {
return NULL;
}
if (!($this->_currentMethod = $this->getVmPluginMethod($cart->virtuemart_paymentmethod_id))) {
$this->clearAmazonSession();
return NULL;
}
$_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession();
if (!$_amazonOrderReferenceId) {
//$msg = vmText::_('VMPAYMENT_AMAZON_PAYWITHAMAZON_BUTTON');
return false;
}
return TRUE; // this method was selected , and the data is valid by default
}
function removeAmazonAddressFromCart ($cart) {
$data = $this->getDataFromSession();
if (isset($data['BT'])) {
$data['BT']['address_type'] = 'BT';
$cart->saveAddressInCart($data['BT'], $data['BT']['address_type'], TRUE);
}
if (isset($data['ST'])) {
$data['ST']['address_type'] = 'ST';
$cart->saveAddressInCart($data['ST'], $data['ST']['address_type'], TRUE);
}
return;
}
/**
* plgVmDisplayListFEPayment
* This event is fired to display the pluginmethods in the cart (edit shipment/payment) for exampel
*
* @param object $cart Cart object
* @param integer $selected ID of the method selected
* @return boolean True on success, false on failures, null when this plugin was not selected.
* On errors, JError::raiseWarning (or JError::raiseError) must be used to set a message.
*
* @author Valerie Isaksen
*/
public function plgVmDisplayListFEPayment (VirtueMartCart $cart, $selected = 0, &$htmlIn) {
return $this->displayListFE($cart, $selected, $htmlIn);
}
/**
* Used when the vmOPC is set to OFF
* @param $cart
* @param $payment_advertise
* @return null
* In case OPC is off: the login widget is displayed on the cart, and on the payment list
*/
function plgVmOnCheckoutAdvertise($cart, &$payment_advertise) {
if (vmConfig::get('oncheckout_opc')==0) {
$html=NULL;
$this->displayListFE($cart, $cart->virtuemart_paymentmethod_id, $html);
}
}
/**
* @param $plugin
* @param $selectedPlugin
* @param $pluginSalesPrice
* @return string
*/
protected function getPluginHtml ($method, $selectedPlugin, $pluginSalesPrice) {
if ($selectedPlugin == $method->virtuemart_paymentmethod_id) {
$checked = 'checked="checked"';
//return NULL;
} else {
$checked = '';
}
$html = '';
if (!class_exists('CurrencyDisplay')) {
require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'currencydisplay.php');
}
$currency = CurrencyDisplay::getInstance();
$costDisplay = "";
if ($pluginSalesPrice) {
$costDisplay = $currency->priceDisplay($pluginSalesPrice);
$costDisplay = '<span class="' . $this->_type . '_cost"> (' . JText::_('COM_VIRTUEMART_PLUGIN_COST_DISPLAY') . $costDisplay . ")</span>";
}
//$html = '<input type="radio" name="virtuemart_paymentmethod_id" id="' . $this->_psType . '_id_' . $plugin->virtuemart_paymentmethod_id . '" value="' . $plugin->virtuemart_paymentmethod_id . '" ' . $checked . ">\n". '<label for="' . $this->_psType . '_id_' . $plugin->virtuemart_paymentmethod_id . '">' . '<span class="' . $this->_type . '">' . $plugin->payment_name . $costDisplay . "</span></label>\n";
// IF NOT SELECTED Then display the Pay With amazon Button
$this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php');
//$this->debug('', 'updateCartWithAmazonAddress', 'debug');
$cart = VirtueMartCart::getCart();
$cartLayout = $cart->layout;
if (empty($cart->products) and $cartLayout == $this->_name) {
//$this->unsetCartLayoutAndPaymentMethod($cart);
$this->leaveAmazonCheckout();
}
$amazonOrderReferenceIdWeight = $this->getAmazonOrderReferenceIdWeightFromSession();
if ($amazonOrderReferenceIdWeight) {
if (isset($amazonOrderReferenceIdWeight['_amazonOrderReferenceId'])) {
$this->_amazonOrderReferenceId = $amazonOrderReferenceIdWeight['_amazonOrderReferenceId'];
}
$referenceIdIsOnlyDigitalGoods = false;
if (isset($amazonOrderReferenceIdWeight['isOnlyDigitalGoods'])) {
$referenceIdIsOnlyDigitalGoods = $amazonOrderReferenceIdWeight['isOnlyDigitalGoods'];
}
}
if (!$this->_amazonOrderReferenceId OR $this->shouldLoginAgain($referenceIdIsOnlyDigitalGoods, $this->isOnlyDigitalGoods($cart))) {
$html .= $this->renderSignInButton($cart);
}
// amazon is not listed in the payment list. JS displays the signin button
return $html;
}
private function unsetCartLayoutAndPaymentMethod ($cart) {
if (!class_exists('VmConfig')) {
require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
}
VmConfig::loadConfig();
$cart->layout = VmConfig::get('cartlayout', 'default');
$cart->virtuemart_paymentmethod_id = 0;
// $cart->prepareAddressDataInCart(); // VM2 function
$cart->prepareAddressFieldsInCart(); // empty BT ?
$cart->setCartIntoSession();
return;
}
/**
* reset the cart layout, unset the paymentmethod, put back the storeAddress
*/
private function leaveAmazonCheckout ($msg = NULL) {
if (!class_exists('VmConfig')) {
require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
}
$cart = VirtueMartCart::getCart();
$cart->layout = VmConfig::get('cartlayout', 'default');
$cart->layoutPath = '';
$cart->virtuemart_paymentmethod_id = 0;
$previousAddress = $this->getBTandSTFromSession();
$cart->BT = $previousAddress['BT'];
$cart->ST = $previousAddress['ST'];
$cart->prepareAddressFieldsInCart(); // in VM2 prepareAddressDataInCart
$cart->setCartIntoSession();
$cart->setOutOfCheckout();
$this->clearAmazonSession();
if ($msg) {
$app = JFactory::getApplication();
$app->enqueueMessage($msg);
}
return;
}
private function setCartLayout ($cart, $intoSession = true) {
if (!class_exists('VmConfig')) {
require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart' . DS . 'helpers' . DS . 'config.php');
}
VmConfig::loadConfig();
$cart->layoutPath = vmPlugin::getTemplatePath($this->_name, 'payment', 'cart');
$cart->layout = 'cart';
if ($intoSession) {
$cart->setCartIntoSession();
}
}
/**
* plgVmonSelectedCalculatePricePayment
* Calculate the price (value, tax_id) of the selected method
* It is called by the calculator
* This function does NOT to be reimplemented. If not reimplemented, then the default values from this function are taken.
* @cart: VirtueMartCart the current cart
* @cart_prices: array the new cart prices
* @return null if the method was not selected, false if the shipping rate is not valid any more, true otherwise
*
*
*/
private static $cartPriceUpdatedDone = false;
public function plgVmonSelectedCalculatePricePayment (VirtueMartCart $cart, array &$cart_prices, &$cart_prices_name) {
if (!($this->selectedThisByMethodId($cart->virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
if (!($this->_currentMethod = $this->getVmPluginMethod($cart->virtuemart_paymentmethod_id))) {
$this->clearAmazonSession();
return NULL;
}
$amazonOrderReferenceIdWeight = $this->getAmazonOrderReferenceIdWeightFromSession();
$this->_amazonOrderReferenceId = $amazonOrderReferenceIdWeight['_amazonOrderReferenceId'];
$referenceIdIsOnlyDigitalGoods = $amazonOrderReferenceIdWeight['isOnlyDigitalGoods'];
$cart_prices_name = '';
$cart_prices['cost'] = 0;
if (!$this->checkConditions($cart, $this->_currentMethod, $cart_prices)) {
//vmInfo('VMPAYMENT_AMAZON_PAYMENT_NOT_AVAILABLE');
//$this->unsetCartLayoutAndPaymentMethod($cart);
$this->leaveAmazonCheckout(vmText::_('VMPAYMENT_AMAZON_PAYMENT_NOT_AVAILABLE'));
return FALSE;
}
$layout = $cart->layout;
if ($this->shouldLoginAgain($referenceIdIsOnlyDigitalGoods, $this->isOnlyDigitalGoods($cart))) {
} else {
$check = self::$cartPriceUpdatedDone;
if (!self::$cartPriceUpdatedDone) {
$cartPriceUpdated = ($this->getAmazonSalesPriceFromSession() == $cart_prices['salesPrice']) ? false : true;
if ($cartPriceUpdated) {
$cart->_dataValidated = false;
$cart->setCartIntoSession();
}
}
$this->renderAddressbookWallet($cart->_dataValidated);
}
$cart_prices_name = $this->renderPluginName($this->_currentMethod);
$this->setCartPrices($cart, $cart_prices, $this->_currentMethod);
if (!self::$cartPriceUpdatedDone) {
$this->setSalesPriceInSession($cart_prices['salesPrice']);
}
self::$cartPriceUpdatedDone = true;
return TRUE;
}
private function shouldLoginAgain ($referenceIdIsOnlyDigitalGoods, $isOnlyDigitalGoods) {
if (($isOnlyDigitalGoods and $referenceIdIsOnlyDigitalGoods) OR (!$isOnlyDigitalGoods and !$referenceIdIsOnlyDigitalGoods)) {
return false;
}
static $enqueueMessageDone = false;
if (!$enqueueMessageDone) {
JFactory::getApplication()->enqueueMessage(vmText::_('VMPAYMENT_AMAZON_CLICK_SHOULD_LOGIN_AGAIN'));
$enqueueMessageDone = true;
}
return true;
}
private function getPixelValue ($value) {
$value = str_replace("px", "", $value);
$value = $value . 'px';
return trim($value);
}
/**
* plgVmOnCheckAutomaticSelectedPayment
* Checks how many plugins are available. If only one, the user will not have the choice. Enter edit_xxx page
* The plugin must check first if it is the correct type
*
* @author Valerie Isaksen
* @param VirtueMartCart cart: the cart object
* @return null if no plugin was found, 0 if more then one plugin was found, virtuemart_xxx_id if only one plugin is found
*
*/
public function plgVmOnCheckAutomaticSelectedPayment (VirtueMartCart $cart, array $cart_prices = array()) {
return $this->onCheckAutomaticSelected($cart, $cart_prices);
}
/**
* This method is fired when showing the order details in the frontend.
* It displays the method-specific data.
*
* @param integer $order_id The order ID
* @return mixed Null for methods that aren't active, text (HTML) otherwise
* @author Valerie Isaksen
*/
public function plgVmOnShowOrderFEPayment ($virtuemart_order_id, $virtuemart_paymentmethod_id, &$payment_name) {
$this->onShowOrderFE($virtuemart_order_id, $virtuemart_paymentmethod_id, $payment_name);
}
/**
* This method is fired when showing when priting an Order
* It displays the the payment method-specific data.
*
* @param integer $_virtuemart_order_id The order ID
* @param integer $method_id method used for this order
* @return mixed Null when for payment methods that were not selected, text (HTML) otherwise
* @author Valerie Isaksen
*/
public function plgVmonShowOrderPrintPayment ($order_number, $method_id) {
return $this->onShowOrderPrint($order_number, $method_id);
}
/**
* Save updated order data to the method specific table
*
* @param array $_formData Form data
* @return mixed, True on success, false on failures (the rest of the save-process will be
* skipped!), or null when this method is not actived.
*
* public function plgVmOnUpdateOrderPayment( $_formData) {
* return null;
* }
*/
/**
* Save updated orderline data to the method specific table
*
* @param array $_formData Form data
* @return mixed, True on success, false on failures (the rest of the save-process will be
* skipped!), or null when this method is not actived.
*
* public function plgVmOnUpdateOrderLine( $_formData) {
* return null;
* }
*/
/**
* plgVmOnEditOrderLineBE
* This method is fired when editing the order line details in the backend.
* It can be used to add line specific package codes
*
* @param integer $_orderId The order ID
* @param integer $_lineId
* @return mixed Null for method that aren't active, text (HTML) otherwise
*
* public function plgVmOnEditOrderLineBE( $_orderId, $_lineId) {
* return null;
* }
*/
/**
* This method is fired when showing the order details in the frontend, for every orderline.
* It can be used to display line specific package codes, e.g. with a link to external tracking and
* tracing systems
*
* @param integer $_orderId The order ID
* @param integer $_lineId
* @return mixed Null for method that aren't active, text (HTML) otherwise
*
* public function plgVmOnShowOrderLineFE( $_orderId, $_lineId) {
* return null;
* }
*/
function plgVmDeclarePluginParamsPaymentVM3( &$data) {
return $this->declarePluginParams('payment', $data);
}
public function plgVmSetOnTablePluginParamsPayment ($name, $id, &$table) {
return $this->setOnTablePluginParams($name, $id, $table);
}
function getEmailCurrency (&$method) {
return $method->payment_currency; // either the vendor currency, either same currency as payment
}
private function saveAmazonOrderReferenceId ($cart) {
$this->_amazonOrderReferenceId = vRequest::getString('session', '');
$this->setAmazonOrderReferenceIdInSession($this->_amazonOrderReferenceId, $this->isOnlyDigitalGoods($cart));
$cart->virtuemart_paymentmethod_id = vRequest::getInt('pm');
}
/*********************/
/* Private functions */
/*********************/
/**
* get the partial shipping address (city, state, postal code, and country) by calling the GetOrderReferenceDetails operation
* to compute taxes and shipping costs or possible applicable shipping speed, and options.
* @param $client
* @param $cart
*/
function updateCartWithAmazonAddress () {
$this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php');
$return = array();
//$this->debug('', 'updateCartWithAmazonAddress', 'debug');
$cart = VirtueMartCart::getCart();
$physicalDestination = $this->getPhysicalDestination();
if (!$physicalDestination) {
$return['error'] = 'NoPhysicalDestination';
$return['error_msg'] = vmText::_('VMPAYMENT_AMAZON_UPDATECART_ERROR');
return $return;
}
$update_data = $this->getUserInfoFromAmazon($physicalDestination);
if (!$this->isValidCountry($update_data['virtuemart_country_id'])) {
$this->updateCartWithDefaultAmazonAddress($cart, $this->isOnlyDigitalGoods($cart));
$country = shopFunctions::getCountryByID($update_data['virtuemart_country_id']);
$cart->_dataValidated = false;
$cart->BT['virtuemart_country_id'] = 0;
$cart->setCartIntoSession();
$return['error'] = 'deliveryCountryNotAllowed';
$return['error_msg'] = vmText::sprintf('VMPAYMENT_AMAZON_UPDATECART_DELIVERYCOUNTRYNOTALLOWED', $country);
return $return;
}
if ($this->isSameAddress($update_data, $cart)) {
$return['error'] = 'sameAddress';
return $return;
}
$update_data ['address_type'] = 'BT';
$cart->saveAddressInCart($update_data, $update_data['address_type'], TRUE);
// update BT and ST with Amazon Partial Address
$prefix = 'shipto_';
$update_data = $this->getUserInfoFromAmazon($physicalDestination, $prefix);
$update_data ['address_type'] = 'ST';
$cart->saveAddressInCart($update_data, $update_data['address_type'], TRUE, $prefix);
$cart->STsameAsBT = false;
$cart->setCartIntoSession();
$return['error'] = 'addressUpdated';
return $return;
}
function getPhysicalDestination () {
$this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession();
if (empty($this->_amazonOrderReferenceId)) {
//vmError('VMPAYMENT_AMAZON_LOGIN');
return FALSE;
}
$orderReferenceDetails = $this->getOrderReferenceDetailsResponse();
if (!$orderReferenceDetails) {
return false;
}
$destination = $orderReferenceDetails->GetOrderReferenceDetailsResult->getOrderReferenceDetails()->getDestination();
if (empty($destination)) {
// plgVmonSelectedCalculatePricePayment is also called in the module
//$this->debug('Destination is empty, noot saving', 'saveAmazonPartialShipmentAddressIncart', 'debug');
return false;
}
$physicalDestination = $destination->getPhysicalDestination();
return $physicalDestination;
}
function updateCartWithDefaultAmazonAddress ($cart, $STsameAsBT = true) {
$this->loadVmClass('VirtueMartCart', JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php');
$this->_amazonOrderReferenceId = $this->getAmazonOrderReferenceIdFromSession();
if (empty($this->_amazonOrderReferenceId)) {
//vmError('VMPAYMENT_AMAZON_LOGIN');
return FALSE;
}
$virtuemart_vendor_id = 1;
$vendorModel = VmModel::getModel('vendor');
$vendorModel->setId($virtuemart_vendor_id);
$vendorFields = $vendorModel->getVendorAddressFields($virtuemart_vendor_id);
$skips = array('name', 'username', 'agreed');
// TODO if asynchronous authorization: we set some default fields to the vendor fields
$update_dataBT = array();
//$update_dataST = array();
$prefix = 'shipto_';
foreach ($vendorFields['fields'] as $field) {
if (!$field['required']) {
continue;
}
if ($field['name'] == 'virtuemart_country_id') {
$update_dataBT[$field['name']] = $field[$field['name']];
$update_dataST[$prefix . $field['name']] = $field[$field['name']];
} elseif ($field['name'] == 'virtuemart_state_id') {
$update_dataBT[$field['name']] = $field[$field['name']];
$update_dataST[$prefix . $field['name']] = $field['value'];
} elseif ($field['name'] == 'email') {
$update_dataBT[$field['name']] = $field['value'];
$update_dataST[$prefix . $field['name']] = $field['value'];
} else {
$update_dataBT[$field['name']] = '-';
$update_dataST[$prefix . $field['name']] = '-';
}
}
$update_dataBT ['address_type'] = 'BT';
$cart->saveAddressInCart($update_dataBT, $update_dataBT['address_type'], TRUE);
if (!$STsameAsBT) {
$update_dataST ['address_type'] = 'ST';
$cart->STsameAsBT = false;
unset($update_dataST['shipto_company']);
$cart->saveAddressInCart($update_dataST, $update_dataST['address_type'], TRUE,$prefix);
} else {
$cart->STsameAsBT = true;
}
$cart->setCartIntoSession();
return true;
}
private function isSameAddress ($update_data, $cart) {
if ($cart->BT['city'] == $update_data['city'] and $cart->BT['virtuemart_country_id'] == $update_data['virtuemart_country_id'] AND $cart->BT['zip'] == $update_data['zip']) {
return true;
}
return false;
}
/**
* IPN_Handler
*
* This trigger is invoked whenever a new notification needs to be processed,
* and will call the IPN API
*
*
*/
private function ipn () {
// ERP mode turns off all automated authorization and capture functionality
// as well as IPN reception and / or polling, and disables any admin UI functionality that may trigger
//If the authorization is done by ERP then the IPN URL set in amazon should not be this one.
// we keep it anyway, for testing purposes
if ($this->isERPModeEnabled() and $this->isAuthorizationDoneByErp()) {
return;
}
// Fetch all HTTP request headers
$headers = getallheaders();
$body = file_get_contents('php://input');
$this->debugLog(var_export($headers, true), 'AMAZON IPN HEADERS debug', 'debug');
$this->debugLog(var_export($body, true), 'AMAZON IPN BODY debug', 'debug');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Client');
$this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
try {
$client = new OffAmazonPaymentsNotifications_Client();
$notification = $client->parseRawMessage($headers, $body);
} catch (OffAmazonPaymentsNotifications_InvalidMessageException $e) {
$this->debugLog($e->getMessage() .' '. __FUNCTION__ . ' $body', 'error');
header("HTTP/1.1 503 Service Unavailable");
exit(0);
}
$notificationType = $notification->getNotificationType();
$this->debugLog($notificationType, 'ipn', 'debug');
if (!$this->isValidNotificationtype($notificationType)) {
$this->debugLog($notificationType, 'ipn NOT isValidNotificationtype', 'error');
return;
}
$notificationClass = 'amazonHelper' . $notificationType;
$notificationFile = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . strtolower($notificationType . '.php');
if (!file_exists($notificationFile)) {
$this->debugLog("Unknown notification Type: " . $notificationType, __FUNCTION__, 'error');
return false;
}
if (!class_exists($notificationClass)) {
require(JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . 'helper.php');
require($notificationFile);
}
$this->debugLog($notificationType, 'ipn', 'debug');
$notificationResponse = new $notificationClass($notification, $this->_currentMethod);
$this->debugLog("<pre>" . var_export($notificationResponse->amazonData, true) . "</pre>", __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) {
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 . '<br/>';
}
parent::debugLog($message, $title, $type, $doVmDebug);
}
private function debug ($subject, $title = '', $echo = true) {
$debug = '<div style="display:block; margin-bottom:5px; border:1px solid red; padding:5px; text-align:left; font-size:10px;white-space:nowrap; overflow:scroll;">';
$debug .= ($title) ? '<br /><strong>' . $title . ':</strong><br />' : '';
//$debug .= '<pre>';
if (is_array($subject)) {
$debug .= str_replace("=>", "⇒", str_replace("Array", "<font color=\"red\"><b>Array</b></font>", nl2br(str_replace(" ", " ", print_r($subject, true)))));
} else {
//$debug .= str_replace("=>", "⇒", str_replace("Array", "<font color=\"red\"><b>Array</b></font>", (str_replace(" ", " ", print_r($subject, true)))));
$debug .= str_replace("=>", "⇒", str_replace("Array", "<font color=\"red\"><b>Array</b></font>", print_r($subject, true)));
}
//$debug .= '</pre>';
$debug .= '</div>';
if ($echo) {
echo $debug;
} else {
return $debug;
}
}
//
// Load classes / files if not exists
//
function loadAmazonServicesClasses () {
$this->loadAmazonClass('OffAmazonPaymentsService_Client');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_SetOrderReferenceDetailsResponse');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_Price');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_OrderTotal');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_SellerOrderAttributes');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_ResponseHeaderMetadata');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_ResponseMetadata');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_AuthorizeResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_AuthorizationDetails');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_AuthorizeResponse');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_Address');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_IdList');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_Status');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_CaptureDetails');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_CaptureResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_GetCaptureDetailsResponse');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_GetCaptureDetailsResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_RefundResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_RefundDetails');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_RefundResponse');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_CloseOrderReferenceRequest');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_GetAuthorizationDetailsResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_GetRefundDetailsResult');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_CloseAuthorizationRequest');
$this->loadAmazonClass('OffAmazonPaymentsService_Model_CloseAuthorizationResult');
}
function loadAmazonNotificationClasses () {
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Client');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_AuthorizationNotification');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_AuthorizationDetails');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_Price');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_IdList');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_Status');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_OrderItemCategories');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_RefundNotification');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_RefundDetails');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_CaptureNotification');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_CaptureDetails');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_IPNNotificationMetadata');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_NotificationImpl');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_SnsNotificationMetadata');
$this->loadAmazonClass('OffAmazonPaymentsNotifications_Model_OrderTotal');
}
function loadAmazonClass ($className) {
if (!class_exists($className)) {
$filePath = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'library' . DS . str_replace('_', DS, $className) . '.php';
if (file_exists($filePath)) {
require $filePath;
return;
} else {
vmError('Programming error: trying to load:' . $filePath);
}
}
}
function loadHelperClass ($className) {
if (!class_exists('amazonHelper')) {
require(JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . 'helper.php');
}
if (!class_exists($className)) {
$fileName = strtolower(str_replace('amazonHelper', '', $className)) . '.php';
$fileNameAbsPath = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . $fileName;
if (file_exists($fileNameAbsPath)) {
require($fileNameAbsPath);
} else {
vmError('Programming error: ' . __FUNCTION__ . ' trying to load:' . $fileNameAbsPath);
}
}
}
function loadVmClass ($className, $fileName) {
if (!class_exists($className)) {
if (file_exists($fileName)) {
require($fileName);
} else {
vmError('Programming error:' . __FUNCTION__ . ' trying to load:' . $fileName);
}
}
}
function getallheaders () {
if (!function_exists('getallheaders')) {
//$this->debugLog("getallheaders PHP function does not exists" . "<pre>" . var_export($_SERVER, true) . "</pre>", __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" . "<pre>" . var_export($headers, true) . "</pre>", __FUNCTION__, 'debug');
return $headers;
} else {
return getallheaders();
}
}
}
// No closing tag