Post by crabwolf » Thu Apr 19, 2012 12:18 am

Hi,

I'm currently working on a site where the client would like to have product details and customer details passed to the sage pay payment gateway. The existing sagepay module only sends order totals, rather than the the full order details the client requires.

Does anyone have any experience of this or any advice as I'm not 100% sure how to approach this!

Thanks in advance.

Newbie

Posts

Joined
Thu Jan 26, 2012 12:14 am

Post by Kinetic » Fri Jun 29, 2012 12:20 am

Hi Avvici,
thanks so much for getting back to me, I've tried so hard to try and understand this, I sort of understand the why just not the how.
Attached are the PDF's from Sage / SagePay for your reference. Some of these can only be downloaded once logged in.
I couldn't agree more about the blowing :D it's had me so confused.

I'm going to try some things out and will let you know.
I'm assuming you mean to edit the template file in catalogue/view/theme/(custom-theme)/template/payment/sagepay.tpl ?

Attachments

API Guide - there's a ref to basket on page 72

Form Protocol and Integration Guideline

Sage 50 - check out page 22


User avatar
New member

Posts

Joined
Fri Aug 19, 2011 4:10 am
Location - UK

Post by Kinetic » Fri Jun 29, 2012 1:11 am

still can't work out what to write in that file.
Obviously something in the format of:
<input type="hidden" name="parametername" value="<?php echo $billing_address; ?>" />
as you said but I'm lost.
I need to send the basket details and include the SKU in the description in square brackets [] as detailed in the sage 50 user guide on page 22. Also something about a colon delimited list. I'm thinking I need to call the info from my database somehow, I just don't know how, not even staring at my database gave me any insight.
I'm not experienced with PHP or much else as you can likely tell, but I'm very determined to learn.

If you can help me work out what I'm supposed to be typing I would be extremely grateful.

Thanks in advance, Kinetic

User avatar
New member

Posts

Joined
Fri Aug 19, 2011 4:10 am
Location - UK

Post by Avvici » Fri Jun 29, 2012 5:43 am

That's "exactly" what you need. Finally some good api documentation. However I looked at the OC sagepay.php control file and it looks like they already have set you up with many parameters. The only one that is not there is the product information which can be easily sent with a string delimited by a ':'. just like the documentation sates. I can do that for you in a bit but I must leave for a while. All you would do is add it to this pile. I was incorrect in suggesting that you add it to the later. And an FYI, you are creating a string to send that ties all of the $data variables together that can be found here:

Code: Select all

$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_code'], $order_info['currency_value'], false);
		$data['Currency'] = $order_info['currency_code'];
		$data['Description'] = sprintf($this->language->get('text_description'), date($this->language->get('date_format_short')), $this->session->data['order_id']);
		$data['SuccessURL'] = str_replace('&', '&', $this->url->link('payment/sagepay/success', 'order_id=' . $this->session->data['order_id']));
		$data['FailureURL'] = str_replace('&', '&', $this->url->link('checkout/checkout', '', 'SSL'));
		
		$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(utf8_decode(implode('&', $crypt_data)), $password));
The html form reflects it like this:

Code: Select all

 <input type="hidden" name="Crypt" value="<?php echo $crypt; ?>" />
I shall help when I return

User avatar
Expert Member

Posts

Joined
Tue Apr 05, 2011 12:09 pm
Location - Asheville, NC

Post by Kinetic » Fri Jun 29, 2012 11:10 pm

Thanks again for your help.
My server has been down all day so I've not been able to test anything, but I think I may be starting to get it (probably not ??? )

Am I to enter:

Code: Select all

$data['Basket'] = Number of lines of detail in the basket field:[sku]Item 1 Description:Quantity of item 1:Unit cost item 1 without tax:Tax applied to item 1:Cost of Item 1 including tax:Total cost of item 1 (Quantity x cost including tax):
somewhere into that file, catalogue/controller/payment/sagepay.php ?

Thanks for your help and I'll await your reply.

The only thing I need to send other than the basics is the SKU which needs to show at the start of the description in []'s. Another concern I have is that I'm using Qphoria's Options Boost module which allows for unique SKU's for each option. For products with options I need to make sure it sends the ob_sku (that's what it is in my database) and not the default sku.

If what I'm asking is too much please let me know.

User avatar
New member

Posts

Joined
Fri Aug 19, 2011 4:10 am
Location - UK

Post by Avvici » Sat Jun 30, 2012 7:31 am

The only think you need to do is pass your products in a string separated by a colon like the documentation suggests. You would simply do this by getting your product data in a forloop and just forming a string every iteration. Just use the cart session already there. Sagepay requires you specify the total quantity of items first then specify each item with it's name, price, and quantity. Perhaps something like this:

Code: Select all

 $count_total_products = 0;
		  //get total product quantities
		   foreach ($this->cart->getProducts() as $product) {
			
			$count_total_products +=  $product['quantity'];
					
			}	
			$productsting = '';
			//sagepay requires colon delimiter. The last 3 fields are left empty with ':' If you want to use those fields then you will need to run another forloop to fetch the totals for combined product quantities. Below is just for name, quantity, and base price.
			foreach ($this->cart->getProducts() as $product) {
			
			$productsting .= $product['name'].':'.$product['quantity'].':'. $this->currency->format($product['price'], $order_info['currency_code'], false, false).':'.':'.':';
					
			}
			//this is the string you will send in the end.
			$main_string_to_send =	$count_total_products.':'.$productsting;
			//send here
			$data['Basket'] = $main_string_to_send;

User avatar
Expert Member

Posts

Joined
Tue Apr 05, 2011 12:09 pm
Location - Asheville, NC

Post by Kinetic » Tue Jul 03, 2012 3:28 am

Further to that, I think I worked out what was causing the error. I was trying to buy a product with options and one without, so once I removed the one with options the error goes away and the sagepay screen loads as usual.
However.... still with no basket contents, just the same as before.
The option thing may be due to me using Options Boost, maybe I should contact Qphoria regarding that.
Let me know what you think I should try next.

Thanks

User avatar
New member

Posts

Joined
Fri Aug 19, 2011 4:10 am
Location - UK

Post by Avvici » Wed Jul 04, 2012 12:02 am

You aren't passing option data, just product data. If you want me to help you get the string properly formated I can but you have to skype me at Involution Media.

User avatar
Expert Member

Posts

Joined
Tue Apr 05, 2011 12:09 pm
Location - Asheville, NC

Post by Kinetic » Wed Jul 04, 2012 12:26 am

Avvici,
thanks for offering to help. I could be at this for days trying to work it out.
Give me 10-15 mins and I'll skype you.

Kenny Kinetic :joker:

User avatar
New member

Posts

Joined
Fri Aug 19, 2011 4:10 am
Location - UK

Post by Avvici » Wed Jul 04, 2012 4:52 am

Solved: (BELOW CODE IS ONLY FOR 3 OF THE 6 POSSIBLE STRING VARIABLE FIELDS ACCORDING TO DOCUMENTATION.)
If you want item tax, line total, and item total then you will have to wait for my vQmod. I will upload the vQmod a little later. This just collects the Quantity, Name, and Item Price

Code: Select all

$count_total_products = 0;
        //get total rows to be sent in string
         foreach ($this->cart->getProducts() as $product) {
         
         $count_total_products++;
               
         }   
         $productstring = '';
         //sagepay requires colon delimiter. The last 3 fields are left empty with ':' If you want to use those fields then you will need to run another forloop to fetch the totals for combined product quantities. Below is just for name, quantity, and base price.
         foreach ($this->cart->getProducts() as $product) {
         //gather SKU for each product.  ugh.....
		 $sku = $this->model_checkout_order->getSku($product['product_id']);
         $productstring .= '['.$sku.']'.$product['name'].':'.$product['quantity'].':'. $this->currency->format($product['price'], $order_info['currency_code'], false, false).':'.'---'.':'.'---'.':'.'---'.':';
               
         }
         //this is the string you will send in the end.
         $main_string_to_send =   $count_total_products.':'.substr_replace($productstring ,"",-1);
         //send here
         $data['Basket'] = $main_string_to_send;
And the function to get the SKU: place in model/checkout/order.php

Code: Select all

public function getSku($product_id) {
		$query = $this->db->query("SELECT sku AS code FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");

		return $query->row['code'];
	}	
That code tags the SKU to the beginning of the product name. If you don't want the SKU then use this version:

Code: Select all

$count_total_products = 0;
        //get total rows to be sent in string
         foreach ($this->cart->getProducts() as $product) {
         
         $count_total_products++;
               
         }   
         $productstring = '';
         //sagepay requires colon delimiter. The last 3 fields are left empty with ':' If you want to use those fields then you will need to run another forloop to fetch the totals for combined product quantities. Below is just for name, quantity, and base price.
         foreach ($this->cart->getProducts() as $product) {
         //gather SKU for each product.  ugh.....
		// $sku = $this->model_checkout_order->getSku($product['product_id']);
         $productstring .= $product['name'].':'.$product['quantity'].':'. $this->currency->format($product['price'], $order_info['currency_code'], false, false).':'.'---'.':'.'---'.':'.'---'.':';
               
         }
         //this is the string you will send in the end.
         $main_string_to_send =   $count_total_products.':'.substr_replace($productstring ,"",-1);
         //send here
         $data['Basket'] = $main_string_to_send;

User avatar
Expert Member

Posts

Joined
Tue Apr 05, 2011 12:09 pm
Location - Asheville, NC

Post by Avvici » Wed Jul 04, 2012 1:38 pm

For those using OPTIONS BOOST that want to pass the option SKU, this checks for existing option SKU and if none, uses the regular SKU:

Code: Select all

$count_total_products = 0;
        //get total rows to be sent in string
         foreach ($this->cart->getProducts() as $product) {
         
         $count_total_products++;
               
         }   
         $productstring = '';
		
         //sagepay requires colon delimiter. The last 3 fields are left empty with ':' If you want to use those fields then you will need to run another forloop to fetch the totals for combined product quantities. Below is just for name, quantity, and base price.
		
         foreach ($this->cart->getProducts() as $product) {
         //gather Option SKU for each product.  If no option sku, use normal skuugh.....		 
			
					$sku = $this->model_checkout_order->getOptionSku($product['product_id']);
					if($sku){
					foreach ($sku as $value){
			       $skucode = $value['ob_sku'];
					}
					}else{
						$skucode = $this->model_checkout_order->getSku($product['product_id']);;
					}
					
					$baseprice = $this->currency->format($product['price'], $order_info['currency_code'], false, false);
					
					
				
				$line_total = $this->currency->format($product['price']  * $product['quantity'], $order_info['currency_code'], $order_info['currency_value']);
				
				
			
		 	//set up Basket String
         $productstring .= '['.$skucode.']'.$product['name'].':'.$product['quantity'].':'.$baseprice.':'.'---'.':'.$line_total.':'.$line_total.':';
               
         }
         //this is the string you will send in the end.
         $main_string_to_send =   $count_total_products.':'.substr_replace($productstring ,"",-1);

         //send here
         $data['Basket'] = $main_string_to_send;
And your model functions:

Code: Select all

public function getSku($product_id) {
		$query = $this->db->query("SELECT sku AS code FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");

		return $query->row['code'];
	}
	public function getOptionSku($product_value_id) {
		$query = $this->db->query("SELECT ob_sku FROM " . DB_PREFIX . "product_option_value WHERE product_id = '" . (int)$product_value_id."'");

		return $query->rows;
	}		

User avatar
Expert Member

Posts

Joined
Tue Apr 05, 2011 12:09 pm
Location - Asheville, NC

Post by Caradiaz » Tue Feb 26, 2013 6:48 pm

Thank you for posting this solution. Quick question - please excuse my ignorance... - where exactly does the code need to be placed in the tlp file? Just before </form> or else?

Many thanks for your help.

Newbie

Posts

Joined
Wed Jan 16, 2013 11:33 pm

Post by Caradiaz » Wed Feb 27, 2013 6:46 pm

I'd be really grateful if someone could please advice about the placement of the above code for get the shopping cart on to SagePay confirmation. I'm not developer and would be grateful for assistance with this.

Many thanks.

Newbie

Posts

Joined
Wed Jan 16, 2013 11:33 pm

Post by toptenweb » Tue Oct 29, 2013 9:54 am

Was there a vqmod version of these changes ever put together? Or even just some details of the model/view/controller files to update?

Newbie

Posts

Joined
Mon Mar 05, 2012 6:38 am

Post by toptenweb » Tue Oct 29, 2013 10:10 am


Newbie

Posts

Joined
Mon Mar 05, 2012 6:38 am
Who is online

Users browsing this forum: No registered users and 95 guests