Post by rog_ashbury » Tue Jun 15, 2010 5:17 am

I'm getting the following error in Sagepay

Undefined index: subtract in /{blah}/{blah}/public_html/catalog/model/checkout/order.php on line 75Notice: Undefined index: $payment_iso_code_2 in /{blah}/{blah}/public_html/catalog/controller/payment/sagepay.php on line 93

I'm also getting this for cheque/money order and bank transfer

Undefined index: subtract in /{blah}/{blah}/public_html/catalog/model/checkout/order.php on line 75

I don't think it's anything I have edited so I think it must be errors in the 1.4.8 code

New member

Posts

Joined
Mon Nov 02, 2009 6:56 am

Post by rog_ashbury » Tue Jun 15, 2010 5:52 pm

OK, I think I've got to the bottom of the Sage Pay problem. There's an unwanted $ sign at line 93


if ($order_info['$payment_iso_code_2'] == 'US') {

should be

if ($order_info['payment_iso_code_2'] == 'US') {

But that still leaves the cheque and bank transfer payment problems with the patch files. My unpatched 1.4.8 now seems to be running OK - it's only when I introduce the patch files that the errors come in.

New member

Posts

Joined
Mon Nov 02, 2009 6:56 am

Post by Qphoria » Thu Jun 17, 2010 5:29 am

Try this to fix the Error Send To Required.

1. EDIT: catalog/controller/payment/sagepay.php

2. FIND:

Code: Select all

$this->model_checkout_order->confirm($this->request->get['order_id'], $this->config->get('sagepay_order_status_id')); 
3. REPLACE WITH:

Code: Select all

$this->model_checkout_order->confirm($data['VendorTxCode'], $this->config->get('sagepay_order_status_id')); 

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by diggydog » Thu Jun 17, 2010 4:22 pm

Hi,

Need some help with a sagepay error that's occurring after upgrading to 1.48 with 1.48b patch. This is what happens:

The buyer is directed to sagepay where they fill in details, the buyer then clicks confirm and the payment processes. An error is then thrown "Error: Email to required" on a white screen. At this point the url relates to the opencart server and not sagepay's server. If you click refresh the payment success screen appears.

The transaction completes ok and all emails are sent including the one to the buyer (from sagepay - so the email address is passed through ok), although the error message and the point at which it happens gives the impression the transaction has failed.

Has anyone come across this before or can offer any pointers? Could it be a token error?

Thanks

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by Qphoria » Thu Jun 17, 2010 9:33 pm

Does anybody know how to read anymore? I try to be patient with you people, but when the post RIGHT ABOVE YOURS offers a solution, it gets pretty damn annoying.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by diggydog » Thu Jun 17, 2010 10:01 pm

Thanks Q, your patience is appreciated. I am sure you to will have a day when you cannot see the wood for the trees.

Great update by the way ;)

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by diggydog » Thu Jun 17, 2010 10:16 pm

Fixing the error creates another issue, when the payment has been successfully been processed the order is not been generated (no order and no confirmation emails. It seems that changing from

Code: Select all

($this->request->get['order_id']

to

Code: Select all

($data['VendorTxCode']

is not returning a value my system is accepting.

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by Qphoria » Thu Jun 17, 2010 10:48 pm

diggydog wrote:I am sure you to will have a day when you cannot see the wood for the trees.
I like this saying :)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by diggydog » Fri Jun 18, 2010 4:23 am

OK, have had a good search through the forums and this issue presents the same as the huge "paypal no order" epitaph found on the forum. The big difference is that this was not (as far as I am aware) an issue in 1.47, it throws an error in 1.48 and turns to "Sagepay No Order" when the suggested error fix is applied.

I have read a fair chunk of the paypal no order thread and to be honest there are that many suggestions I cannot be sure any of them may be relevant to this situation, also it appears that the issue was resolved for paypal a while back. If this is the case I feel it would be unlikely the exact same situation would occur in a different payment module.

If anyone can offer any guidance it would be appreciated.

Thanks

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by diggydog » Sun Jun 20, 2010 4:09 am

I am no expert so maybe someone would be so kind as to explain this to me. Below (at the bottom) is the code from the sagepay module. Before I make the advised change

Code: Select all

$this->model_checkout_order->confirm($this->request->get['order_id'], $this->config->get('sagepay_order_status_id'));
to

Code: Select all

$this->model_checkout_order->confirm($data['VendorTxCode'], $this->config->get('sagepay_order_status_id'));
I get the email to required white screen error. If I click refresh then the Success screen appears. The order is correctly placed in admin with the correct status (a successful order with payment confirmed).

If I make the advised change I get the Success screen appear (no error) but the order is incorrectly placed in admin as a missing order even though payment has been successfully taken.

Sagepay is clearly returning the correct data from the order because it is clearly visible in admin and works (with error) before the change is applied. After making the change the payment confirmation data is no longer being correctly mapped.

So I am looking at this thinking:
1) Is there another element of the code I have to change to map the data correctly. If so, what is it because I cannot see it.
2) If it works almost correctly before the change, what causes the "Error: email to required"? Can the code be changed to suppress the error? Is it really required if it is already in the clients data?

3) Am I looking at this the right way?

Code: Select all

<?php
class ControllerPaymentSagepay extends Controller {
	protected function index() {
		$this->language->load('payment/sagepay');
		
		$this->data['button_confirm'] = $this->language->get('button_confirm');
		$this->data['button_back'] = $this->language->get('button_back');
		
		if ($this->config->get('sagepay_test') == 'live') {
    		$this->data['action'] = 'https://live.sagepay.com/gateway/service/vspform-register.vsp';
		} elseif ($this->config->get('sagepay_test') == 'test') {
			$this->data['action'] = 'https://test.sagepay.com/gateway/service/vspform-register.vsp';		
		} elseif ($this->config->get('sagepay_test') == 'sim') {
    		$this->data['action'] = 'https://test.sagepay.com/simulator/vspformgateway.asp';
  		} 
		
		$vendor = $this->config->get('sagepay_vendor');
		$password = $this->config->get('sagepay_password');		
		
		$this->load->model('checkout/order');
		
		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
		
		$data = array();
		
		$data['VendorTxCode'] = $this->session->data['order_id'];
		$data['ReferrerID'] = 'E511AF91-E4A0-42DE-80B0-09C981A3FB61';
		$data['Amount'] = $this->currency->format($order_info['total'], $order_info['currency'], $order_info['value'], FALSE);
		$data['Currency'] = $order_info['currency'];
		$data['Description'] = sprintf($this->language->get('text_description'), date($this->language->get('date_format_short')), $this->session->data['order_id']);
		$data['SuccessURL'] = HTTPS_SERVER . 'index.php?route=payment/sagepay/success&order_id=' . $this->session->data['order_id'];
		
		if ($this->request->get['route'] != 'checkout/guest_step_3') {
			$data['FailureURL'] = HTTPS_SERVER . 'index.php?route=checkout/payment';
		} else {
			$data['FailureURL'] = HTTPS_SERVER . 'index.php?route=checkout/guest_step_2';
		}
		
		$data['CustomerName'] = html_entity_decode($order_info['payment_firstname'] . ' ' . $order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
		$data['SendEMail'] = '1';
		$data['CustomerEMail'] = $order_info['email'];
		$data['VendorEMail'] = $this->config->get('config_email');  
		
		$data['BillingFirstnames'] = $order_info['payment_firstname'];
        $data['BillingSurname'] = $order_info['payment_lastname'];
        $data['BillingAddress1'] = $order_info['payment_address_1'];
		
		if ($order_info['payment_address_2']) {
        	$data['BillingAddress2'] = $order_info['payment_address_2'];
		}
		
		$data['BillingCity'] = $order_info['payment_city'];
       	$data['BillingPostCode'] = $order_info['payment_postcode'];	
        $data['BillingCountry'] = $order_info['payment_iso_code_2'];
		
		if ($order_info['payment_iso_code_2'] == 'US') {
			$data['BillingState'] = $order_info['payment_zone_code'];
		}
		
		$data['BillingPhone'] = $order_info['telephone'];
		
		if ($this->cart->hasShipping()) {
			$data['DeliveryFirstnames'] = $order_info['shipping_firstname'];
        	$data['DeliverySurname'] = $order_info['shipping_lastname'];
        	$data['DeliveryAddress1'] = $order_info['shipping_address_1'];
		
			if ($order_info['shipping_address_2']) {
        		$data['DeliveryAddress2'] = $order_info['shipping_address_2'];
			}
		
        	$data['DeliveryCity'] = $order_info['shipping_city'];
        	$data['DeliveryPostCode'] = $order_info['shipping_postcode'];
        	$data['DeliveryCountry'] = $order_info['shipping_iso_code_2'];
		
			if ($order_info['shipping_iso_code_2'] == 'US') {
				$data['DeliveryState'] = $order_info['shipping_zone_code'];
			}
		
			$data['DeliveryPhone'] = $order_info['telephone'];
		} else {
			$data['DeliveryFirstnames'] = $order_info['payment_firstname'];
        	$data['DeliverySurname'] = $order_info['payment_lastname'];
        	$data['DeliveryAddress1'] = $order_info['payment_address_1'];
		
			if ($order_info['payment_address_2']) {
        		$data['DeliveryAddress2'] = $order_info['payment_address_2'];
			}
		
        	$data['DeliveryCity'] = $order_info['payment_city'];
        	$data['DeliveryPostCode'] = $order_info['payment_postcode'];
        	$data['DeliveryCountry'] = $order_info['payment_iso_code_2'];
		
			if ($order_info['$payment_iso_code_2'] == 'US') {
				$data['DeliveryState'] = $order_info['payment_zone_code'];
			}
		
			$data['DeliveryPhone'] = $order_info['telephone'];			
		}
		
		$data['AllowGiftAid'] = '0';
		
		if (!$this->config->get('sagepay_transaction')) {
			$data['ApplyAVSCV2'] = '0';
		}
		
 		$data['Apply3DSecure'] = '0';
		
		$this->data['transaction'] = $this->config->get('sagepay_transaction');
		$this->data['vendor'] = $vendor;
		
		$crypt_data = array();
   
		foreach($data as $key => $value){
   			$crypt_data[] = $key . '=' . $value;
		}

		$this->data['crypt'] = base64_encode($this->simpleXor(implode('&', $crypt_data), $password));
		
		if ($this->request->get['route'] != 'checkout/guest_step_3') {
			$this->data['back'] = HTTPS_SERVER . 'index.php?route=checkout/payment';
		} else {
			$this->data['back'] = HTTPS_SERVER . 'index.php?route=checkout/guest_step_2';
		}
		
		$this->id = 'payment';

		if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/sagepay.tpl')) {
			$this->template = $this->config->get('config_template') . '/template/payment/sagepay.tpl';
		} else {
			$this->template = 'default/template/payment/sagepay.tpl';
		}	
		
		$this->render();		
	}
	
	public function success() {
		if (isset($this->request->get['crypt'])) {
			$string = base64_decode(str_replace(' ', '+', $this->request->get['crypt']));
			$password = $this->config->get('sagepay_password');	

			$output = $this->simpleXor($string, $password);
			
			$data = $this->getToken($output);
		
			if ($data) {
				$this->load->model('checkout/order');
		
				$this->model_checkout_order->confirm($data['VendorTxCode'], $this->config->get('sagepay_order_status_id'));

				$message = '';
		
				if (isset($data['VPSTxId'])) { 
					$message .= 'VPSTxId: ' . $data['VPSTxId'] . "\n";
				}

				if (isset($data['TxAuthNo'])) {
					$message .= 'TxAuthNo: ' . $data['TxAuthNo'] . "\n";
				}

				if (isset($data['AVSCV2'])) {
					$message .= 'AVSCV2: ' . $data['AVSCV2'] . "\n";
				}

				if (isset($data['AddressResult'])) {
					$message .= 'AddressResult: ' . $data['AddressResult'] . "\n";
				}
				
				if (isset($data['PostCodeResult'])) {
					$message .= 'PostCodeResult: ' . $data['PostCodeResult'] . "\n";
				}
				
				if (isset($data['CV2Result'])) {
					$message .= 'CV2Result: ' . $data['CV2Result'] . "\n";
				}

				if (isset($data['3DSecureStatus'])) {
					$message .= '3DSecureStatus: ' . $data['3DSecureStatus'] . "\n";
				}

				if (isset($data['CAVV'])) {
					$message .= 'CAVV: ' . $data['CAVV'] . "\n";
				}
				
				if (isset($data['CardType'])) {
					$message .= 'CardType: ' . $data['CardType'] . "\n";
				}
				
				if (isset($data['Last4Digits'])) {
					$message .= 'Last4Digits: ' . $data['Last4Digits'] . "\n";
				}
				
				$this->model_checkout_order->update($this->request->get['order_id'],, $this->config->get('sagepay_order_status_id'), $message, FALSE);

				$this->redirect(HTTP_SERVER . 'index.php?route=checkout/success');
			}
		}
	}	 
	
	private function simpleXor($string, $password) {
		$data = array();

		for ($i = 0; $i < strlen(utf8_decode($password)); $i++) {
			$data[$i] = ord(substr($password, $i, 1));
		}

		$output = '';

		for ($i = 0; $i < strlen(utf8_decode($string)); $i++) {
    		$output .= chr(ord(substr($string, $i, 1)) ^ ($data[$i % strlen(utf8_decode($password))]));
		}

		return $output;		
	}
	
	private function getToken($string) {
  		$tokens = array(
   			'Status',
    		'StatusDetail',
    		'VendorTxCode',
   			'VPSTxId',
    		'TxAuthNo',
    		'Amount',
   			'AVSCV2', 
    		'AddressResult', 
    		'PostCodeResult', 
    		'CV2Result', 
    		'GiftAid', 
    		'3DSecureStatus', 
    		'CAVV',
			'AddressStatus',
			'CardType',
			'Last4Digits',
			'PayerStatus',
			'CardType'
		);		
		
  		$output = array();
		$data = array();
  
  		for ($i = count($tokens) - 1; $i >= 0; $i--){
    		$start = strpos($string, $tokens[$i]);
    		
			if ($start){
     			$data[$i]['start'] = $start;
     			$data[$i]['token'] = $tokens[$i];
			}
		}
  
		sort($data);
		
		for ($i = 0; $i < count($data); $i++){
			$start = $data[$i]['start'] + strlen($data[$i]['token']) + 1;

			if ($i == (count($data) - 1)) {
				$output[$data[$i]['token']] = substr($string, $start);
			} else {
				$length = $data[$i+1]['start'] - $data[$i]['start'] - strlen($data[$i]['token']) - 2;
				
				$output[$data[$i]['token']] = substr($string, $start, $length);
			}      

		}
  
		return $output;
	}	
}
?>
Any help would be appreciated.

Thanks.

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by diggydog » Sun Jun 20, 2010 6:24 pm

For anyone else having this issue the immediate solution is not the one advised in the posts above. It is suggested that you try this:
For those getting "Error: Email to required!"
This is due to the additional alert email check adding a single "blank" email to the additional email list. It doesn't stop any orders, but it throws an ugly error.

Quick fix:
1. EDIT: catalog/model/checkout/order.php

2. FIND (~line 379):

Code: Select all

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_alert_emails'));
foreach ($emails as $email) {
    $mail->setTo($email);
    $mail->send();
}

3. REPLACE WITH:

Code: Select all

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_alert_emails'));
foreach ($emails as $email) {
    if ($email) {
        $mail->setTo($email);
        $mail->send();
    }
}
You can find it in this thread http://forum.opencart.com/viewtopic.php ... 3&start=60
Hope it works for you.

Diggydog
http://www.promoteyourproducts.co.uk


Newbie

Posts

Joined
Thu Apr 29, 2010 6:24 pm
Location - UK

Post by unknownmale » Wed Jul 07, 2010 7:21 pm

Thanks for this!!!

Life saver.







diggydog wrote:For anyone else having this issue the immediate solution is not the one advised in the posts above. It is suggested that you try this:
For those getting "Error: Email to required!"
This is due to the additional alert email check adding a single "blank" email to the additional email list. It doesn't stop any orders, but it throws an ugly error.

Quick fix:
1. EDIT: catalog/model/checkout/order.php

2. FIND (~line 379):

Code: Select all

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_alert_emails'));
foreach ($emails as $email) {
    $mail->setTo($email);
    $mail->send();
}

3. REPLACE WITH:

Code: Select all

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_alert_emails'));
foreach ($emails as $email) {
    if ($email) {
        $mail->setTo($email);
        $mail->send();
    }
}
You can find it in this thread http://forum.opencart.com/viewtopic.php ... 3&start=60
Hope it works for you.

New member

Posts

Joined
Fri May 21, 2010 8:39 pm

Post by Qphoria » Wed Jul 07, 2010 9:17 pm

After you made the change for the Error Email To required, now if you change the original line to $data['VendorTxCode'] does it work?

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am
Who is online

Users browsing this forum: No registered users and 11 guests