Page 1 of 1
Suspected Payment bug in 1.4.8
Posted: Tue Jun 15, 2010 5:17 am
by rog_ashbury
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
Re: Suspected Payment bug in 1.4.8
Posted: Tue Jun 15, 2010 5:52 pm
by rog_ashbury
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.
Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 5:29 am
by Qphoria
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'));
Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 4:22 pm
by diggydog
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
Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 9:33 pm
by Qphoria
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.
Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 10:01 pm
by diggydog
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

Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 10:16 pm
by diggydog
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
to
is not returning a value my system is accepting.
Re: Suspected Payment bug in 1.4.8
Posted: Thu Jun 17, 2010 10:48 pm
by Qphoria
diggydog wrote:I am sure you to will have a day when you cannot see the wood for the trees.
I like this saying

Re: Suspected Payment bug in 1.4.8
Posted: Fri Jun 18, 2010 4:23 am
by diggydog
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
Re: Suspected Payment bug in 1.4.8
Posted: Sun Jun 20, 2010 4:09 am
by diggydog
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.
Re: Suspected Payment bug in 1.4.8
Posted: Sun Jun 20, 2010 6:24 pm
by diggydog
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.
Re: Suspected Payment bug in 1.4.8
Posted: Wed Jul 07, 2010 7:21 pm
by unknownmale
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.
Re: Suspected Payment bug in 1.4.8
Posted: Wed Jul 07, 2010 9:17 pm
by Qphoria
After you made the change for the Error Email To required, now if you change the original line to $data['VendorTxCode'] does it work?