News:

Looking for documentation? Take a look on our wiki

Main Menu

Possible VM with 2CO Solution

Started by Silent_Dave, March 23, 2011, 13:46:40 PM

Previous topic - Next topic

Silent_Dave

Hi there,

I have taken this from another thread (http://forum.virtuemart.net/index.php?topic=55302.15) and placed it here in hopes of helping other poor souls who are struggling with this payment method. I am not guaranteeing it as a solution, but offering it as a possible solution and/or the basis for making a better solution.

*** Here We Go! ***

The Code to be placed in you 2CheckOut configuration (found in Payment Methods in your VM admin):

<?php
// Get ship_to information
if( $db->f("user_info_id") != $dbbt->f("user_info_id"))
{
$q2  "SELECT * FROM #__vm_user_info WHERE user_info_id='".$db->f("user_info_id")."'"
$dbst = new ps_DB;
$dbst->setQuery($q2);
$dbst->query();
$dbst->next_record();
} else {
$dbst $dbbt;

           
$q3 "SELECT * FROM #__vm_order_item WHERE user_info_id='".$db->f("user_info_id")."'";
$dbcprod = new ps_DB;
$dbcprod->setQuery($q3);
$dbcprod->query();
$dbcprod->next_record();

//sort out user orders
for($i 0$i count($dbcprod->record); $i++){ $orders[$i] = $dbcprod->record[$i]->order_id; }
arsort($orders);
$this_order_id current($orders); //sets most recent order number for user

//gets all product info entries for this order number
for($i 0$i count($dbcprod->record); $i++)

if($dbcprod->record[$i]->order_id == $this_order_id) { $this_order[$i] = $dbcprod->record[$i]; }
}
sort($this_order);

//2co c_prods to send
//creates 2co c_prod parameters
for($i 0$i count($this_order); $i++)

$twoco_prod_info["c_prod_$i"] = $this_order[$i]->order_item_sku .","$this_order[$i]->product_quantity;
$twoco_prod_info["c_name_$i"] = $this_order[$i]->order_item_name;
$twoco_prod_info["c_price_$i"] = $this_order[$i]->product_final_price;
$twoco_prod_info["c_description_$i"] = $this_order[$i]->order_item_name .","$this_order[$i]->product_attribute;

}
   
//Authnet vars to send
$formdata = array (
'x_login' => TWOCO_LOGIN,
'x_email_merchant' => ((TWOCO_MERCHANT_EMAIL == 'True') ? 'TRUE' 'FALSE'),
'id_type' => 1//added for c_prod compliance

// Customer Name and Billing Address
'x_first_name' => $dbbt->f("first_name"),
'x_last_name' => $dbbt->f("last_name"),
'x_company' => $dbbt->f("company"),
'x_address' => $dbbt->f("address_1"),
'x_city' => $dbbt->f("city"),
'x_state' => $dbbt->f("state"),
'x_zip' => $dbbt->f("zip"),
'x_country' => $dbbt->f("country"),
'x_phone' => $dbbt->f("phone_1"),
'x_fax' => $dbbt->f("fax"),
'x_email' => $dbbt->f("email"),
 
// Customer Shipping Address
'x_ship_to_first_name' => $dbst->f("first_name"),
'x_ship_to_last_name' => $dbst->f("last_name"),
'x_ship_to_company' => $dbst->f("company"),
'x_ship_to_address' => $dbst->f("address_1"),
'x_ship_to_city' => $dbst->f("city"),
'x_ship_to_state' => $dbst->f("state"),
'x_ship_to_zip' => $dbst->f("zip"),
'x_ship_to_country' => $dbst->f("country"),
 
'x_invoice_num' => $db->f("order_id"),
'merchant_order_id' => $db->f("order_number"),
'x_receipt_link_url' => SECUREURL."2checkout_notify.php"
 );

$formdata array_merge($twoco_prod_info$formdata); //combine formdata with twoco_prod_info so c_prod info gets sent to 2co
 
if( TWOCO_TESTMODE == "Y" )
$formdata['demo'] = "Y";
       
$version "2";
$url "https://www.2checkout.com/checkout/spurchase";
    
//Convert the currency 
$my_2co_default_currency 'EUR';
$order_total $db->f("order_total");
if (
$db->f('order_currency') != $my_2co_default_currency 
{
$order_total $GLOBALS['CURRENCY']->convert$db->f("order_total") , $db->f('order_currency'), $my_2co_default_currency );
}
$formdata['x_amount'] = number_format($order_total2'.''');

if( 
$page == "checkout.thankyou" )
{
$query_string "?";
foreach( $formdata as $name => $value )
{
$query_string .= $name"=" urlencode($value) ."&";
}
vmRedirect$url $query_string );
} else {
//build the post string
$poststring '';
foreach($formdata AS $key => $val)
{
$poststring .= "<input type='hidden' name='$key' value='$val' />
"
;

    
//old buy logo: https://www.2checkout.com/images/buy_logo.gif
?>

<form id="cho" action="<?php echo $url ?>" method="post" target="_blank">
<?php echo $poststring?>
<p><font size=+1>Click on the Image below to pay...</font></p>
<input type="image" name="submit" src="https://www2.2checkout.com/static/checkout/CheckoutButton2COCards.gif" border="0" alt="Make payments with 2Checkout, it's fast and secure!" title="Pay your Order with 2Checkout, it's fast and secure!" />
</form>
<?php 
}
?>



Ensure you have entered your 2CO Vendor ID and Secret Word as they appear in your 2CO account into the settings.

Set "Order Status for successful transactions" to "Confirmed"

Set "Order Status for failed transactions" to "Canceled"

Save these settings.

Note: You do NOT need to add you "Approved URL" to your site management settings in the 2CO Vendor Admin area. This is included in the code above.

Ensure you have moved/copied 2checkout_notify.php from ROOT/administrator/components/com_virtuemart to your site root (i.e. if you were to type in the URL to this file it would appear like this: www.yoursite.com/2checkout_notify.php)

Now make a test order.

The code, as created on the original thread, passes through the product name and description (one for each item ordered in the cart) to 2CO (so your customer will see his/her ordered items there as well, not some meaningless session number), sends the full and correct customer info to 2CO (no more parameter errors), converts the currency if needed (make sure you have set it correctly using the currency identifiers supplied by 2CO), and removes the need to click on the 2CO image to go through to payment - you are immediately redirected to 2CO.

I have used the 2CO Single Page payment method in the code above. If you wish to use the standard multi-page 2CO payment chain, change the following line from the code:

https://www.2checkout.com/checkout/spurchase

To:

https://www.2checkout.com/checkout/purchase


I'd like to thank all of the contributors to the original thread for their sterling work - they saved me many hours, although I ended up spending almost as many hours trying to find out how to get the order confirmation to work! But we're a little bit closer now.

If this works, or if you find cleaner/better methods of getting this code into action, please post them - 2CO & VM users really need to stick together!

Silent Dave

marcusa007

Very nice, I just changed it to this code and it works great. Thanks. This was something that cost me hours already and I only got it to work with the garbled code being transferred to 2CO in the past. Lot's of people abort the order process at that point. I don't blame them if they get the feeling their info got all messed up in the transfer to the payment site. Again nice work and thanks for putting it in a new thread I would have never found this otherwise. One quick question: in 2CO do you have under notifications/settings global settings all set to http://www.yoursite.com/2checkout_notify.php

Thanks for the info.

Markus

Silent_Dave

Hi Markus,

I leave the notifications blank, actually ... However, I manually check 2CO daily (every working day, Mon-Fri). If all is good, the items are shipped, and I set the status to shipped from the orders section of VM with the option to notify the customer checked (I use Interamind's VM Emails solution - truly excellent addition to VM).

I would rather not have an automatic message be passed through notifying of fraud or suchlike.

However, I HAVE NOT TESTED this at all, as it seemed that it could only be fully tested with live purchasing. So, really, I'm in no position to comment.

But blank has been fine for me. But if you go for blank, you will have to check your 2CO regularly.

I'm glad that this helped you, though! If you try the notifications out, let me know - I'd be interested in that. Right now, I'm not brave enough to try it with a live site (with a VM Store that is getting a pretty pleasing workout these days!)

Best,

Dave

marcusa007

Thanks for the quick answer. So by leaving them all blank - after the order is finished by the customer it changes it automatically to confirmed or do you have to change that by hand as well in VM.


Silent_Dave

Hi Markus,

If you have set your Payment Method settings so that a successful transaction is "confirmed", you will see this reflected in the Orders list in the VM Admin.

You only need to change the status to "shipped" if you are shipping tangible goods.

The only other time a manual change might occur is on refunding .. but I haven't done this as yet ... time will tell - another hurdle to cross later :)

Sending the notification to the notify script for Refund issued might work ... but it's a question of what does the string sent back contain? the 2conotify script will seek a merchant_order_id - and looking at the info about the notification on 2CO, I'm not certain that info is passed back for refunds, for example.

They use vendor_order_id ... which might be solved by adding this line to the script:

'vendor_order_id' => $db->f("order_number")

Like so:

<?php
// Get ship_to information
if( $db->f("user_info_id") != $dbbt->f("user_info_id"))
{
$q2  "SELECT * FROM #__vm_user_info WHERE user_info_id='".$db->f("user_info_id")."'"
$dbst = new ps_DB;
$dbst->setQuery($q2);
$dbst->query();
$dbst->next_record();
} else {
$dbst $dbbt;

           
$q3 "SELECT * FROM #__vm_order_item WHERE user_info_id='".$db->f("user_info_id")."'";
$dbcprod = new ps_DB;
$dbcprod->setQuery($q3);
$dbcprod->query();
$dbcprod->next_record();

//sort out user orders
for($i 0$i count($dbcprod->record); $i++){ $orders[$i] = $dbcprod->record[$i]->order_id; }
arsort($orders);
$this_order_id current($orders); //sets most recent order number for user

//gets all product info entries for this order number
for($i 0$i count($dbcprod->record); $i++)

if($dbcprod->record[$i]->order_id == $this_order_id) { $this_order[$i] = $dbcprod->record[$i]; }
}
sort($this_order);

//2co c_prods to send
//creates 2co c_prod parameters
for($i 0$i count($this_order); $i++)

$twoco_prod_info["c_prod_$i"] = $this_order[$i]->order_item_sku .","$this_order[$i]->product_quantity;
$twoco_prod_info["c_name_$i"] = $this_order[$i]->order_item_name;
$twoco_prod_info["c_price_$i"] = $this_order[$i]->product_final_price;
$twoco_prod_info["c_description_$i"] = $this_order[$i]->order_item_name .","$this_order[$i]->product_attribute;

}
   
//Authnet vars to send
$formdata = array (
'x_login' => TWOCO_LOGIN,
'x_email_merchant' => ((TWOCO_MERCHANT_EMAIL == 'True') ? 'TRUE' 'FALSE'),
'id_type' => 1//added for c_prod compliance

// Customer Name and Billing Address
'x_first_name' => $dbbt->f("first_name"),
'x_last_name' => $dbbt->f("last_name"),
'x_company' => $dbbt->f("company"),
'x_address' => $dbbt->f("address_1"),
'x_city' => $dbbt->f("city"),
'x_state' => $dbbt->f("state"),
'x_zip' => $dbbt->f("zip"),
'x_country' => $dbbt->f("country"),
'x_phone' => $dbbt->f("phone_1"),
'x_fax' => $dbbt->f("fax"),
'x_email' => $dbbt->f("email"),
 
// Customer Shipping Address
'x_ship_to_first_name' => $dbst->f("first_name"),
'x_ship_to_last_name' => $dbst->f("last_name"),
'x_ship_to_company' => $dbst->f("company"),
'x_ship_to_address' => $dbst->f("address_1"),
'x_ship_to_city' => $dbst->f("city"),
'x_ship_to_state' => $dbst->f("state"),
'x_ship_to_zip' => $dbst->f("zip"),
'x_ship_to_country' => $dbst->f("country"),
 
'x_invoice_num' => $db->f("order_id"),
'merchant_order_id' => $db->f("order_number"),
        
'vendor_order_id' => $db->f("order_number"),
'x_receipt_link_url' => SECUREURL."2checkout_notify.php"
 );

$formdata array_merge($twoco_prod_info$formdata); //combine formdata with twoco_prod_info so c_prod info gets sent to 2co
 
if( TWOCO_TESTMODE == "Y" )
$formdata['demo'] = "Y";
       
$version "2";
$url "https://www.2checkout.com/checkout/spurchase";
    
//Convert the currency 
$my_2co_default_currency 'EUR';
$order_total $db->f("order_total");
if (
$db->f('order_currency') != $my_2co_default_currency 
{
$order_total $GLOBALS['CURRENCY']->convert$db->f("order_total") , $db->f('order_currency'), $my_2co_default_currency );
}
$formdata['x_amount'] = number_format($order_total2'.''');

if( 
$page == "checkout.thankyou" )
{
$query_string "?";
foreach( $formdata as $name => $value )
{
$query_string .= $name"=" urlencode($value) ."&";
}
vmRedirect$url $query_string );
} else {
//build the post string
$poststring '';
foreach($formdata AS $key => $val)
{
$poststring .= "<input type='hidden' name='$key' value='$val' />
"
;

    
//old buy logo: https://www.2checkout.com/images/buy_logo.gif
?>

<form id="cho" action="<?php echo $url ?>" method="post" target="_blank">
<?php echo $poststring?>
<p><font size=+1>Click on the Image below to pay...</font></p>
<input type="image" name="submit" src="https://www2.2checkout.com/static/checkout/CheckoutButton2COCards.gif" border="0" alt="Make payments with 2Checkout, it's fast and secure!" title="Pay your Order with 2Checkout, it's fast and secure!" />
</form>
<?php 
}
?>


But I cannot be certain of this, and I think it's making the script a bit "clunky" looking ... Someone with a proper knowledge of php might be able to provide a more elegant solution. I will be performing some maintenance on my own site either tonight or tomorrow night, and will test these notifications during the downtime. If I find any solutions of use, I'll let you know.

Best,

Dave

marcusa007

Have you also noticed that the order confirmation email sent by 2co still garbles the Merchant Order ID and also has some problems in the item listing ->
Vendor Product ID : c_prod_0
Product Description : La Mer by LA MER,
Product Name : La Mer by LA MER
Quantity : 1
Base Price : 0.00

As you can see some fields it passes back correctly in the email but Vendor Product ID and Base Price are messed up. I think the customer gets the same email from 2co. Not too big of a deal since they paid at this point and the total amount matches. But it is odd how all matches on the single page checkout but in the confirmation it's messed up.

Cheers,

Markus

Silent_Dave

Yes, this is something I've been trying to figure out ...

But for me it wasn't a huge problem - as long as the product info was correctly displayed ... and the amount charged remained as it should. Return Customers have actually commented on the fact that they can see their ordered products listed in the 2CO area, whereas before it was just nonsense. It really helps customer confidence.

The c_prod_0 that appears should be the SKU ...

But I'll take a look at this ... probably something simple to fix, actually ... Right now I've been chasing other non-VM bugs and glitches on my site. But I'll get on the case tonight :)

Dave

Silent_Dave

Hi Markus,

Still have some tests to run - will keep you posted.

Dave

marcusa007

Very Cool, thanks for the update.

Silent_Dave

Hi again,

I have had a look at this ... and by accident discovered something.

I was having an issue with shipping rates - I had two bands, one free, the other $5 ...

It was failing to work. Customers in the $5 band were not being charged, or were being overcharged ($5 per item instead of per order).

So I went to Configuration, and enabled all of the steps in the checkout process ...

I ran a test order ...

Worked, solving the shipping rates issue.

And then I noticed that all the info in the emails delivered in confirmation (I use Interamind's VM Email solution) had the correct info - no "c_prod_0" etc.

So I ran another test order, and sure enough, the information displayed by 2CO is correct.

If I was to fault anything, it is the fact that you can only remove the entire order from 2CO, not individual items within the order ... but I can only begin to imagine the kind of headache it would be to solve this (if it is indeed solvable at all).

However, it seems that enabling all the steps for checkout should remove the issue. This is something of a trade-off, of course.

But I guess it points the way forward for developing this code further.

So enable the 4 steps and see what happens for you. I know that in my site (which also runs JomSocial) the registration process allowed customers to skip adding a shipping address, so this wasn't passed through (resulting in a default USA as country with no address supplied - we had to ship to the billing address). Now it will be without fail (we hope - I guess that depends on the customer).

There are still aspects of the 2CO system I want to check, though in  terms of their passbacks to the VM system (cancellations and refunds, etc), but I'm not certain when I'll have the time. And fortunately for me, these don't happen very often, so complete manual processing is not a major time-drain.

I've been asked a few specific questions via PM, and I'll try to address them here when I get the chance!

Best,

Dave

fddlss

Thanks for the code! It works great and it just solved all the issues I was having with 2CO. Checkout is easier, less confusing, the page looks better and I didn't have to customize the checkout page/button or anything like that. Easy checkout, nice page, clear order confirmations = my life easier and happy customers. Thank you!

Jumbo!

Order status auto confirmation still does not work with these codes. Any other suggestion??

DaveD

Silent Dave,

Great contribution, thanks for sharing it.  It makes the checkout process much cleaner and professional!

I'm just testing it out and noticed that when I have multiple products, somehow it doesn't pass through the proper subtotal and totals to be billed.  I have shipping turned off since my products are downloadable.  Any suggestions??

Thanks,

Dave

DaveD

OK, I figured it out.  In the Payment Extra Info, it was set to EUR, for some reason I thought it would just default to whatever the store default currency was, so I changed the code from...

//Convert the currency
$my_2co_default_currency = 'EUR';

to...

//Convert the currency
$my_2co_default_currency = 'USD';

Thanks again, awesome contribution!

Dave



shakensoul

A couple of questions,

By default, using this method, the order status is not being updated to confirmed after successful payment confirmation.

By following the instructions on this topic

http://forum.virtuemart.net/index.php?topic=91355.0

if we change

Quotefrom this(about line 70)
    'x_invoice_num' => $db->f("order_id"),

to this
    'x_invoice_num' => $db->f("order_number"),

the order status changes to confirmed after payment.

But it garbles the payment infromation...

Original and modified screenshots, it adds session numbers to the product ID and description.

Any solution for this ?



[attachment cleanup by admin]