Jump to content

  • You cannot start a new topic
  • You cannot reply to this topic

Fix empty cart if checkout fails Rate Topic   - - - - -

 
  • Zyles
  • Senior Member
  • Members
  • Join Date: 06-Nov 06
  • 596 posts

Posted 02 March 2007 - 02:03 AM #1

I had a problem with a customer who ordered with credit card and she entered the wrong CVV number by accident. So the order failed. Now she went back and the cart was all empty, so she had to put all the products back in the cart and checkout again. The problem this time was that she didn't put the same products in the cart cause it was quite plenty.

So I lost money.

Luckily I accidently stumbled upon the code that caused this and here is the fix. Upon failed checkout the cart inventory remains. Upon completed or processed checkout the cart is emptied.

If you want to make sure you make most out of your sales, you might want to install this.

Enjoy.



Edit core/fn_cart.php:

Find:
// Empty cart
sess_register('cart');
$cart = array('user_data' => $cart['user_data'], 'profile_id' => @$cart['profile_id'], 'user_id' => @$cart['user_id']);

Replace with:
// Empty cart only if successful order
// MOD: empty_cart_zyles
if ($order_info['status'] == 'P' || $order_info['status'] == 'O') {
	sess_register('cart');
	$cart = array('user_data' => $cart['user_data'], 'profile_id' => @$cart['profile_id'], 'user_id' => @$cart['user_id']);
}


This was tested on 1.3.4 SP2 but may apply to all versions.
Marketing tip:

Did you know a targeted e-mail marketing campaign can bring conversion rates up to 3.9%? By using reliable e-mail marketing software you can upsell to existing customers on a tight budget. If you are not using e-mail marketing you are missing out big time. I recommend and use Aweber.

 
  • Zyles
  • Senior Member
  • Members
  • Join Date: 06-Nov 06
  • 596 posts

Posted 02 March 2007 - 02:33 AM #2

Here is a bonus. When order fails, it will just show an error message and not the whole order info as it may confuse the user that doesn't read everything and think it was successful.


Edit skins/YOURSKIN/customer/ordes_pages/order_details.tpl:

Find:
{capture name="mainbox"}

Add above:
{if $order_info.status != 'F'}

Find:
{include file="common_templates/mainbox.tpl" title=$lang.order_info content=$smarty.capture.mainbox}

Add below:
{/if}

Marketing tip:

Did you know a targeted e-mail marketing campaign can bring conversion rates up to 3.9%? By using reliable e-mail marketing software you can upsell to existing customers on a tight budget. If you are not using e-mail marketing you are missing out big time. I recommend and use Aweber.

 
  • RipVan100
  • Member
  • Members
  • Join Date: 09-Jan 07
  • 33 posts

Posted 02 March 2007 - 10:30 PM #3

Thanks so much for this mod, Zyles. Restocking a cart on a failed transaction is a real bummer. Thanks for supplying some good code to fix it.

 
  • RipVan100
  • Member
  • Members
  • Join Date: 09-Jan 07
  • 33 posts

Posted 02 March 2007 - 11:11 PM #4

ghghkghkgjh

 
  • Brandito
  • Member
  • Members
  • Join Date: 17-Dec 06
  • 82 posts

Posted 05 March 2007 - 07:30 PM #5

Hey Zyles, thanks for this fix. I havn't had a chance to test it yet, but it is an awesome bug fix :cool:
[SIZE="1"]Current Version:
CS Cart 1.3.4 SP2

Current Mods installed:
Thickbox (with e-menu) : Tabbed product details : Previous & Next Navigation (with SEO mod by SWS) : Manufacturer META tags[/SIZE]

 
  • SWS
  • Senior Member
  • Members
  • Join Date: 30-Oct 06
  • 798 posts

Posted 30 April 2007 - 04:55 PM #6

I went a slightly different route.. instead of removing all details I added a "retry payment" using a really ****py link ;-P yet to be styled properly

orders_pages/order_details.tpl
Replacing the lines inbetween the red section...




{capture name="mainbox"}

[COLOR="Red"]{if $order_info}
<div align="right">{include file="buttons/button_popup.tpl" but_text=$lang.print_invoice but_href="`$index_script`?`$target_name`=orders&`$mode_name`=print_invoice&order_id=`$order_info.order_id`" width="800" height="600"}</div>
<table cellpadding="0" cellspacing="0" width="100%" border="0">
<tr>
	<td>[/COLOR]
<table width="100%" border="0" cellpadding="2" cellspacing="0">
  <tr>
    <td colspan="3" align="right"><div align="center"><font size='6'><b>{$lang.status}</b>:{include file="orders_pages/order_status.tpl" status=$order_info.status display="view" name="update_order[status]"}</font></div></td>
  </tr>
  <tr>
    <td colspan="3" align="right"> </td>
  </tr>
   {if $order_info.status != 'P'}
  <tr>
    <td colspan="3" align="right"><div align="center" class="mainbox-title-bg"><a href="index.php?target=checkout&mode=checkout" class="text-button-link">Click here to retry your order or change payment details </a></p>
    </div></td>
  </tr>
  {/if}
  <tr>
    <td colspan="3" align="right"> </td>
  </tr>
  <tr>
    <td align="right"><div align="left"><font size='4'></font><font size='4'><b>{$lang.order}</b></font>: <font size='4'>#{$order_info.order_id}</font></div></td>
    <td width="9%"> </td>
    <td width="26%"><p align="right"><font size='4'><b>{$lang.date}</b>:{$order_info.timestamp|date_format:"`$settings.Appearance.date_format`, `$settings.Appearance.time_format`"}</font></p></td>
  </tr>
</table>


	[COLOR="Red"]</td>
	{if $settings.Modules.barcode == 'Y'}
	<td align="right">{include file="addons/barcode/barcode.tpl" id=$order_info.order_id}</td>
	{/if}
</tr>
</table>

<p><br>
{include file="common_templates/subheader.tpl" title=$lang.products_information}[/COLOR]



As you will see, the order status is now huge too, so no confusion :P
[SIZE=3][/SIZE]

 
  • sholand
  • Senior Member
  • Members
  • Join Date: 16-Jan 07
  • 142 posts

Posted 03 May 2007 - 09:20 PM #7

I have to thank you guys for this fix. I had CS quote me on this functionality and then I saw this thread. This is such a logical way to handle a failed transaction. Thanks again for your great work.

 
  • sholand
  • Senior Member
  • Members
  • Join Date: 16-Jan 07
  • 142 posts

Posted 03 May 2007 - 10:24 PM #8

One more small fix. Right now if the card is declined, e-mails are still sent to the customer and to the order dept. etc.
By putting the same if statement in the e-mail notification section you can stop that

	if (!defined('ORDER_NOTIFICATION_SENT')) {
           // Send e-mails only if successful order
           // MOD: 
          [COLOR="Red"]if ($order_info['status'] == 'P' || $order_info['status'] == 'O') 
             {
[/COLOR]
		// [Send email notification]
		$smarty_mail->assign_by_ref('order_info', $order_info);

		// Send notification to customer
		$smarty_mail->assign('order_status', fn_get_order_status_data($order_info['status'], $order_info['lang_code']));
		fn_send_mail($order_info['email'], $settings['Company']['company_orders_department'], 'orders/order_notification_subj.tpl', 'orders/order_notification.tpl', '', $order_info['lang_code']);

		// Translate descriptions to admin language
		fn_translate_products($order_info['items'], 'product', $settings['Appearance']['admin_default_language']);

		// Send notification to order department
		$smarty_mail->assign('order_status', fn_get_order_status_data($order_info['status'], $settings['Appearance']['admin_default_language']));
		fn_send_mail($settings['Company']['company_orders_department'], $order_info['email'], 'orders/order_notification_subj.tpl', 'orders/order_notification.tpl', '', $settings['Appearance']['admin_default_language']);
	  [COLOR="Red"]}[/COLOR]
        }
	// /[Send email notification]

Also, when the screen comes back after failure it still shows the Order Placed language tag (which is confusing if the order failed). Just change this...
if (substr_count('OP', $order_info['status'])>0) {
		fn_set_notification('N','Order Placed',fn_get_lang_var('text_order_placed_successfully'));
	} elseif ($order_info['status'] == 'B') { //backordered
		fn_set_notification('N',fn_get_lang_var('order_placed'),fn_get_lang_var('text_order_backordered'));
	} else {
		[COLOR="Red"]fn_set_notification('E','Order FAILED',fn_get_lang_var('text_order_placed_error'));[/COLOR]
	}


 
  • tletourneau
  • Senior Member
  • Members
  • Join Date: 13-Apr 07
  • 179 posts

Posted 05 May 2007 - 03:58 PM #9

Scholand,

What file are those mods for?
Thanks,
Tom
Version - 3.0.4
Hosting - RangeHosting.us

 
  • baballuci
  • Senior Member
  • Members
  • Join Date: 02-Mar 06
  • 969 posts

Posted 05 May 2007 - 08:14 PM #10

Looks like they're for core/fn_cart.php
Charlie

 
  • tletourneau
  • Senior Member
  • Members
  • Join Date: 13-Apr 07
  • 179 posts

Posted 05 May 2007 - 08:34 PM #11

Charlie,

Thanks, that was it.
Thanks,
Tom
Version - 3.0.4
Hosting - RangeHosting.us

 
  • coder
  • Senior Member
  • Members
  • Join Date: 19-Jun 07
  • 411 posts

Posted 24 June 2007 - 03:31 AM #12

During test runs, we are doing some dummy credit catd payments. The email sent does mention that there was payment failure..... order details page is blank? Shouldn't it display a payment failure message?

 
  • Zyles
  • Senior Member
  • Members
  • Join Date: 06-Nov 06
  • 596 posts

Posted 24 June 2007 - 04:21 AM #13

It should create an order with status Failed.
Marketing tip:

Did you know a targeted e-mail marketing campaign can bring conversion rates up to 3.9%? By using reliable e-mail marketing software you can upsell to existing customers on a tight budget. If you are not using e-mail marketing you are missing out big time. I recommend and use Aweber.

 
  • coder
  • Senior Member
  • Members
  • Join Date: 19-Jun 07
  • 411 posts

Posted 24 June 2007 - 06:07 AM #14

It should create an order with status Failed.


Zyles... you are correct it does for the email sent.... but at the same time it redirects to order details pages.... which is blank.

From customer perpsective, unless he checks his email, he won't know the order failed?

 
  • Zyles
  • Senior Member
  • Members
  • Join Date: 06-Nov 06
  • 596 posts

Posted 24 June 2007 - 06:29 AM #15

It should display a message that the payment failed. Perhaps you edited something wrong? (Make sure you did post 2)

The fix is not foolproof and is not intended to be. It is up to CS-Cart to fix the real problem, which is a more streamlined and easier checkout.

This just makes sure the cart does not get emptied.
Marketing tip:

Did you know a targeted e-mail marketing campaign can bring conversion rates up to 3.9%? By using reliable e-mail marketing software you can upsell to existing customers on a tight budget. If you are not using e-mail marketing you are missing out big time. I recommend and use Aweber.

 
  • coder
  • Senior Member
  • Members
  • Join Date: 19-Jun 07
  • 411 posts

Posted 24 June 2007 - 02:55 PM #16

Here is a bonus. When order fails, it will just show an error message and not the whole order info as it may confuse the user that doesn't read everything and think it was successful.


Edit skins/YOURSKIN/customer/ordes_pages/order_details.tpl:

Find:

{capture name="mainbox"}

Add above:
{if $order_info.status != 'F'}

Find:
{include file="common_templates/mainbox.tpl" title=$lang.order_info content=$smarty.capture.mainbox}

Add below:
{/if}


Her is the modified code
{* $Id: order_details.tpl 2660 2006-12-25 06:31:33Z zeke $	*}

{if $order_info.status != 'F'}

{capture name="mainbox"}

{if $order_info}
<div align="right">{include file="buttons/button_popup.tpl" but_text=$lang.print_invoice but_href="`$index_script`?`$target_name`=orders&`$mode_name`=print_invoice&order_id=`$order_info.order_id`" width="800" height="600"}</div>
<table cellpadding="0" cellspacing="0" width="100%" border="0">
<tr>
	<td>
		<table cellpadding="2" cellspacing="0" border="0">
		<tr>
			<td align="right"><b>{$lang.order}</b>: </td><td>#{$order_info.order_id}</td>
		</tr>
		<tr>
			<td align="right"><b>{$lang.date}</b>: </td><td>{$order_info.timestamp|date_format:"`$settings.Appearance.date_format`, `$settings.Appearance.time_format`"}</td>
		</tr>
		<tr>
			<td align="right"><b>{$lang.status}</b>: </td><td>{include file="orders_pages/order_status.tpl" status=$order_info.status display="view" name="update_order[status]"}</td>
		</tr>
		</table>
	</td>
	{if $settings.Modules.barcode == 'Y'}
	<td align="right">{include file="addons/barcode/barcode.tpl" id=$order_info.order_id}</td>
	{/if}
</tr>
</table>

<p><br>
{include file="common_templates/subheader.tpl" title=$lang.products_information}
<table cellpadding="2" cellspacing="1" border="0" width="100%">
<tr>
	<td width="100%" class="table-head"> {$lang.product}</td>
	<td class="table-head"> {$lang.options}</td>
	<td class="table-head" align="center"> {$lang.price}</td>
	<td class="table-head" align="center"> {$lang.amount}</td>
	{if $order_info.use_discount}
	<td class="table-head" align="center">{$lang.discount}</td>
	{/if}
	{if $order_info.taxes}
	<td class="table-head" align="center"> {$lang.tax}</td>
	{/if}

	<td class="table-head" align="center"> {$lang.subtotal}</td>
</tr>
{foreach from=$order_info.items item="oi" key="key"}
{if $settings.Modules.product_configurator == 'Y' && $oi.extra.configuration}
		{include file="addons/product_configurator/order_details_configurable.tpl"}
{elseif $settings.Modules.product_configurator != 'Y' || !$oi.extra.in_configuration}
<tr {cycle values="class='table-row', "}>
	<td> <a href="{$index_script}?{$target_name}=products&product_id={$oi.product_id}">{$oi.product}</a>
	{if ($order_info.status == 'P' || $order_info.status == 'C') && $oi.extra.is_edp}
	<div align="right"><a href="{$index_script}?{$target_name}=products&{$mode_name}=download&ekey={$oi.extra.ekey}"><b>[{$lang.download}]</b></a></div>
	{/if}
	</td>
	<td align="left" nowrap="nowrap">{include file="common_templates/options_info.tpl" product_options=$oi.product_options}</td>
	<td align="right" nowrap="nowrap">
		{include file="common_templates/price.tpl" value=$oi.price}</td>
	<td align="center"> {$oi.amount}</td>
	{if $order_info.use_discount}
	<td align="right" class="side-padding" nowrap="nowrap">
		{if $oi.extra.discount|floatval}{include file="common_templates/price.tpl" value=$oi.extra.discount}{else}-{/if}</td>
	{/if}
	{if $order_info.taxes}
	<td align="center" class="side-padding" nowrap="nowrap">
		{include file="common_templates/price.tpl" value=$oi.tax_value}</td>
	{/if}
	<td align="right"> <b>{include file="common_templates/price.tpl" value=$oi.subtotal}</b></td>
</tr>
{/if}
{/foreach}
</table>

<p><br>
{include file="common_templates/subheader.tpl" title=$lang.order_info}
<table>
{if $order_info.payment_id}
<tr>
	<td><b>{$lang.payment_method}: </b></td>
	<td>{$order_info.payment_method.payment} {if $order_info.payment_method.description}({$order_info.payment_method.description}){/if}</td>
</tr>
{/if}
{if $order_info.shipping}
<tr>
	<td><b>{$lang.shipping}: </b></td>
	<td>{$order_info.shipping}</td>
</tr>
{/if}
<tr>
	<td><b>{$lang.subtotal}: </b></td>
	<td>{include file="common_templates/price.tpl" value=$order_info.subtotal}</td>
</tr>
{if $order_info.shipping_cost|floatval}
<tr>
	<td><b>{$lang.shipping_cost}: </b></td>
	<td>{include file="common_templates/price.tpl" value=$order_info.shipping_cost}</td>
</tr>
{/if}
{if $order_info.discount|floatval}
<tr>
	<td nowrap="nowrap"><b>{$lang.including_discount}:</b></td>
	<td nowrap="nowrap">
		{include file="common_templates/price.tpl" value=$order_info.discount}</td>
</tr>
{/if}
{if $order_info.coupons}
{foreach from=$order_info.coupons item="coupon" key="key"}
<tr>
	<td colspan="2" nowrap="nowrap">
	<b>{$lang.discount_coupon}</b> {$key} ({if $coupon.free_shipping == 'Y'}{$lang.free_shipping}{else}{include file="common_templates/price.tpl" value=$coupon.value number_type=$coupon.value_type}{/if})
	</td>
</tr>
{/foreach}
{/if}
{if $order_info.taxes}
<tr>
	<td align="left"><b>{$lang.including_taxes}:<b></td>
	<td> </td>
</tr>
{foreach from=$order_info.taxes item=tax_data}
<tr>
	<td>{$tax_data.description} {include file="common_templates/price.tpl" value=$tax_data.rate_value number_type=$tax_data.rate_type} ({if $tax_data.regnumber}{$tax_data.regnumber}{/if}) </td>
	<td>{include file="common_templates/price.tpl" value=$tax_data.tax_subtotal}</td>
</tr>
{/foreach}
{/if}
{if $order_info.tax_exempt == 'Y'}
<tr>
	<td><b>{$lang.tax_exempt}</b></td>
	<td> </td>
<tr>
{/if}

{if $order_info.payment_surcharge|floatval}
<tr>
	<td>{$lang.payment_surcharge}: </td>
	<td>{include file="common_templates/price.tpl" value=$order_info.payment_surcharge}</td>
</tr>
{/if}
<tr>
	<td><b>{$lang.total}: </b></td>
	<td><b>{include file="common_templates/price.tpl" value=$order_info.total}</b></td>
</tr>
<tr>
	<td valign="top"><b>{$lang.customer_notes}: </b></td>
	<td>{$order_info.notes|replace:"\n":"<BR>"|default:"-"}</td>
</tr>

{if $order_info.tracking_number}
<tr>
	<td><b>{$lang.tracking_number}: </b></td>
	<td>
	
	<table cellpadding="0" cellspacing="0" border="0">
	<tr>
		<td><b>{$order_info.tracking_number}</b>  </td>
		{if $order_info.carrier}
		<td>
			{if $order_info.carrier == 'USP'}
				{assign var="url" value="http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?strOrigTrackNum=`$order_info.tracking_number`"}
			{elseif $order_info.carrier == 'UPS'}
				{assign var="url" value="http://wwwapps.ups.com/WebTracking/processInputRequest?AgreeToTermsAndConditions=yes&tracknum=`$order_info.tracking_number`"}
			{elseif $order_info.carrier == 'FDX'}
				{assign var="url" value="http://fedex.com/Tracking?action=track&tracknumbers=`$order_info.tracking_number`"}
			{elseif $order_info.carrier == 'AUP'}
				<form name="tracking_form" target="_blank" action="http://ice.auspost.com.au/index.asp?ShowFirstScreenOnly=FALSE&ShowFirstRecOnly=TRUE" method="post">
				<input type="hidden"  name="txtItemNumber" maxlength="13" value="{$order_info.tracking_number}" />
				</form>		
			{elseif $order_info.carrier == 'DHL' || $order_info.carrier == 'ARB'}
				<form name="tracking_form" target="_blank" method="post" action="http://track.dhl-usa.com/TrackByNbr.asp?nav=Tracknbr">
				<input type="hidden" name="txtTrackNbrs" value="{$order_info.tracking_number}" />
				</form>
			{/if}

			{if $url}
			{include file="buttons/button.tpl" but_text=$lang.track but_href=$url but_target="_blank" but_arrow=true}
			{else}
			{include file="buttons/button.tpl" but_text=$lang.track but_onclick="document.forms['tracking_form'].submit();" but_arrow=true}
			{/if}
		</td>
		{/if}
	</tr>
	</table>

	</td>
</tr>
{/if}
</table>
<table cellpadding="2" cellspacing="1" border="0" width="100%">
<tr>
	<td>{php}
	    $ip = (isset($_SERVER)) ? $_SERVER['REMOTE_ADDR'] : $HTTP_SERVER_VARS['REMOTE_ADDR'];
	    $host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
	    $CurrentDate = date("m-d-Y h:ia");
	    $Ref= $_SERVER['HTTP_REFERER'];
	    $Bro= $_SERVER['HTTP_USER_AGENT'];
	    $user = (empty($_REQUEST['name'])) ? '' : $_REQUEST['name'];
	    echo('<br><b>Access Time</b> : '.$CurrentDate.'<br><b>User / IP</b> : '.$user.' '.$ip.' <br><b>Browser </b>: '.$Bro.'<br><b>Remote Host [if avaliable] </b>: '.$host. "<br /><br>\n");
	{/php}</td>

</tr>
</table>
<p><br />
{include file="common_templates/subheader.tpl" title=$lang.customer_information}

{* Customer info *}
{include file="profiles_pages/profiles_info.tpl" user_data=$order_info location="I"}
{* /Customer info *}

{/if}
{/capture}
{include file="common_templates/mainbox.tpl" title=$lang.order_info content=$smarty.capture.mainbox}
{/if}

{if $settings.Modules.discussion == 'Y'}
{include file="addons/discussion/discussion.tpl" object_id=$order_info.order_id object_type="O" title=$lang.discussion_title_order}
{/if}

{if $smarty.get.confirmation == 'Y'}
{* place any code you wish to display on this page right after the order has been placed *}
{/if}

Can someone suggest where we made the mistake.

Thanks in advance.

 
  • Zyles
  • Senior Member
  • Members
  • Join Date: 06-Nov 06
  • 596 posts

Posted 24 June 2007 - 08:30 PM #17

Did you flush the cache?

Don't know what would cause the blank page. See if it happends with another payment provider. Might be the module.
Marketing tip:

Did you know a targeted e-mail marketing campaign can bring conversion rates up to 3.9%? By using reliable e-mail marketing software you can upsell to existing customers on a tight budget. If you are not using e-mail marketing you are missing out big time. I recommend and use Aweber.

 
  • tjmaxwell
  • Member
  • Members
  • Join Date: 18-Jun 07
  • 55 posts

Posted 24 June 2007 - 09:10 PM #18

My order details page appears blank too after adding this hack.

 
  • coder
  • Senior Member
  • Members
  • Join Date: 19-Jun 07
  • 411 posts

Posted 25 June 2007 - 06:59 PM #19

My order details page appears blank too after adding this hack.


Were you able resolve this?

 
  • tjmaxwell
  • Member
  • Members
  • Join Date: 18-Jun 07
  • 55 posts

Posted 25 June 2007 - 07:48 PM #20

No, but I didn't try exceptionally hard. The instructions are incredibly straight-forward, so I can't see what I did wrong. In the end, I just used a slightly modified version of SWS's code for when orders are declined.

Were you able resolve this?