Zen Cart Logo
Forums / Addon Payment Modules / Create a new module for International Checkout payment module

Create a new module for International Checkout payment module

Locked

Views: 13,210

Results 1 to 20 of 64
This thread is locked. New replies are disabled.
3 Dec 2009, 8:09 PM
#1
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Create a new module for International Checkout payment module

I am trying to create a module to integrate International Checkout, as a payment module.

I was searching and couldn't find if there is a specific template to be used or what kind of guidelines I have to use in order to integrate the code.

Any suggestions on how to do it will be helpful as I want to avoid conflicts or malfunctions.

This is just a sample of the info that must be retrieved.

For example, if there are 2 items in your cart, then fields ItemDescription, ItemSKU, ItemSize, ItemColor, ItemWeight, ItemQuantity,
ItemPrice, ItemImage, ImgHeight, ImgWidth will be:
ItemDescription1, ItemSKU1, ItemSize1, ItemColor1, ItemWeight1, ItemQuantity1, ItemPrice1, ItemHazardous1, ItemImage1,
ImgHeight1, ImgWidth1
And:
ItemDescription2, ItemSKU2, ItemSize2, ItemColor2, ItemWeight2, ItemQuantity2, ItemPrice2, ItemHazardous2, ItemImage2,
ImgHeight2, ImgWidth2
This is how we’ll recognize how many items are in your cart and will enable the transfer of their values respectively. This integer value
will always be started from 1. (i.e. “ItemDescription1”).

8 Dec 2009, 4:14 PM
#2
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

Where I can get information to add a button over my existing payment options without having to create a new payment module?

I just want to add a button in the shopping cart, as the payment module wiki doc is completely obscure and complex and I don't have the time to devote to develop a new module ...

8 Dec 2009, 5:02 PM
#3
stevesh avatar

stevesh

Black Belt

Join Date:
Feb 2005
Location:
Lansing, Michigan USA
Posts:
19,793
Plugin Contributions:
2

Re: Create a new module for International Checkout payment module

I doubt if you can. Zencart is designed to work through its built-in checkout process.

What sort of payment process were you thinking of?

8 Dec 2009, 9:03 PM
#4
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

It's a payment and checkout system called 'International Checkout', they work like Paypal express or Google checkout, by providing a checkout button >>> see this store that has it >>>

http://outdoorpros.com

I was trying to work with their developers to do a simple integration with Zencart unfortunately the instructions for creating a module are too vague and obscure ...

I am not that familiar building classes and with OOP, so don't even know where to start, if I wanted to look at other payment modules for clues each has it's own rules ...

8 Dec 2009, 9:14 PM
#5
afo avatar

afo

Totally Zenned

Join Date:
Aug 2004
Location:
New York City
Posts:
6,800
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

Zen Cart doesn't work that way. You can't just include a button for the payment processing. It's far more complicated than that since you have to pass information from the cart to the payment processor. A module would be required.

9 Dec 2009, 2:36 AM
#6
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

That's exactly what I thought but the wiki on writing a module is REALLY obscure ... it lacks any guidelines except the structure ...

So i was trying to find out an alternative way ... I need this module ASAP and I don't have the time to devote to create by myself nor the resources to pay for it ...

10 Dec 2009, 7:15 AM
#7
zamzom avatar

zamzom

New Zenner

Join Date:
Jun 2009
Location:
Europe
Posts:
60
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

icecold:

That's exactly what I thought but the wiki on writing a module is REALLY obscure ... it lacks any guidelines except the structure ...
YEAH, TELL ME ABOUT IT! :wacko:

I am not the person to explain "How to write a correct payment module", but i can tell you what i have done.
(Well, follow at your own risk coz my payment module isn't yet perfect and it messes up when returned from payment gateway :lamo:
http://www.zen-cart.com/forum/showthread.php?t=143210)

I have taken one of the payment modules (paypalipn) and modified it; i chose that module since it had the talkback module (ipn_main_handler.php) with the payment gateway, which i also needed.

First obeying the file structure, i have copied all the files i might have edited, in a new directory, and edited their name to my module name(includes/modules/payment/).
I first set up the payment class and it's functions (migrated from paypal.php). The functions in this class are called from various places in other routines depending on the payment module customer choses. One example is the checkout_process.php where inside there are calls to for example $payment_modules->before_process() and $payment_modules->after_order_create($insert_id) functions and you know in which order they are called. One important function is process_button function which is executed when your customer hits order confirm button in the final checkout page.

So the first thing not to do: Since the functions in the payment class is called elsewhere, they should remain. However, unless you know exactly what they are doing, to begin with you can empty inside them and return false to keep their functionality.

Then comes the admin functions such as install, remove, keys (check?). These define how you can install the module in the admin section and your module variables. Keep or change the variables according to your use. You will recognize that there are database construction commands there, you will need to change the database name to yours. You will have to find where the names are defined and add your own definition (use Developers Tool Kit in the admin section to search the keywords). Create new files as needed. When you do this your module is ready to be installed in the admin section. Well, it doesn't have any functionality yet, but at least you can install it.

So this is at least what you need to do for the beginning, and not even the visible portion of the iceberg. I will continue for more later on, if i have time and if there is interest. In the mean time i hope the other more experienced people will drop a few words of instructions as well.

11 Dec 2009, 4:43 PM
#8
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

zamzom:

YEAH, TELL ME ABOUT IT! :wacko:

I am not the person to explain "How to write a correct payment module", but i can tell you what i have done.
(Well, follow at your own risk coz my payment module isn't yet perfect and it messes up when returned from payment gateway :lamo:
http://www.zen-cart.com/forum/showthread.php?t=143210)

I have taken one of the payment modules (paypalipn) and modified it; i chose that module since it had the talkback module (ipn_main_handler.php) with the payment gateway, which i also needed.

First obeying the file structure, i have copied all the files i might have edited, in a new directory, and edited their name to my module name(includes/modules/payment/).
I first set up the payment class and it's functions (migrated from paypal.php). The functions in this class are called from various places in other routines depending on the payment module customer choses. One example is the checkout_process.php where inside there are calls to for example $payment_modules->before_process() and $payment_modules->after_order_create($insert_id) functions and you know in which order they are called. One important function is process_button function which is executed when your customer hits order confirm button in the final checkout page.

So the first thing not to do: Since the functions in the payment class is called elsewhere, they should remain. However, unless you know exactly what they are doing, to begin with you can empty inside them and return false to keep their functionality.

Then comes the admin functions such as install, remove, keys (check?). These define how you can install the module in the admin section and your module variables. Keep or change the variables according to your use. You will recognize that there are database construction commands there, you will need to change the database name to yours. You will have to find where the names are defined and add your own definition (use Developers Tool Kit in the admin section to search the keywords). Create new files as needed. When you do this your module is ready to be installed in the admin section. Well, it doesn't have any functionality yet, but at least you can install it.

So this is at least what you need to do for the beginning, and not even the visible portion of the iceberg. I will continue for more later on, if i have time and if there is interest. In the mean time i hope the other more experienced people will drop a few words of instructions as well.
Thanks for your post ...
It seems no one wants to help on this ...

11 Dec 2009, 7:20 PM
#9
stevesh avatar

stevesh

Black Belt

Join Date:
Feb 2005
Location:
Lansing, Michigan USA
Posts:
19,793
Plugin Contributions:
2

Re: Create a new module for International Checkout payment module

icecold:

It seems no one wants to help on this ...

Not true. We'd all like to help, but this requires programming skills most of us don't have. Those who do usually get paid for this kind of work.

20 Dec 2009, 6:20 PM
#10
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

stevesh:

Not true. We'd all like to help, but this requires programming skills most of us don't have. Those who do usually get paid for this kind of work.

Well I am a computer engineer not the usual non-tech shopper owner ... I was looking into guidelines, I don't have time to study and figure out how all the scripts work, because I have to run my biz, I am not a module developer, I modified several things but it will be good if a good guide was something less complex than 'here is the structure', at least a list of the functions required to run a payment module, that's the open source way, to share and develop by many, and debug so we can build better apps ...

It's really crazy to have to reverse engineer all payment modules ...

20 Dec 2009, 8:50 PM
#11
zamzom avatar

zamzom

New Zenner

Join Date:
Jun 2009
Location:
Europe
Posts:
60
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

icecold:

Well I am a computer engineer not the usual non-tech shopper owner ... I was looking into guidelines, I don't have time to study and figure out how all the scripts work, because I have to run my biz, I am not a module developer, I modified several things but it will be good if a good guide was something less complex than 'here is the structure', at least a list of the functions required to run a payment module, that's the open source way, to share and develop by many, and debug so we can build better apps ...

It's really crazy to have to reverse engineer all payment modules ...

Well, i am not a computer engineer/programmer but i am a reverse engineer!
:smartalec:

Btw, I am intending to update the Wiki pages
http://www.zen-cart.com/wiki/index.php/Developers_-_Payment_Classes

:flex:

4 Jan 2010, 8:52 PM
#12
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

zamzom:

Well, i am not a computer engineer/programmer but i am a reverse engineer!
:smartalec:

Btw, I am intending to update the Wiki pages
http://www.zen-cart.com/wiki/index.php/Developers_-_Payment_Classes

:flex:

Great post ZamZom! Please note that post was not intended for you!
There are many people thinking they will get cash from everything ... and forgot about the basic principles of open source, that is to share and develop together for the greater good.

6 Jan 2010, 9:41 PM
#13
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

I have been working on the module for a while and I have a few questions regarding the process_button method from paypal.php.

function process_button() {
   global $db, $order, $currencies, $currency;
   $options = array();
   $optionsCore = array();
   $optionsPhone = array();
   $optionsShip = array();
   $optionsLineItems = array();
   $optionsAggregate = array();
   $optionsTrans = array();
   $buttonArray = array();

   $this->totalsum = $order->info['total'];

From the above I understand these arrays holds the different data, needed to be submitted, but in my case I need only to submit:

$optionsLineItems as it is the one controlling the ordered products list, my module needs only to submit:

<input type="hidden" name="ItemStore1" value="theoutletseason"> <input type="hidden" name="ItemDescription1" value="first item"> <input type="hidden" name="ItemSKU1" value="product number of first item"> <input type="hidden" name="ItemSize1" value="size of first item"> <input type="hidden" name="ItemColor1" value="color of first item"> <input type="hidden" name="ItemQuantity1" value="quantity of first item"> <input type="hidden" name="ItemPrice1" value="price of the first"> <input type="hidden" name="ItemImage1" value="COMPLETE path of their image" />

So I thought if I modify slightly the code of function ipn_getLineItemDetails() from the paypal_functions.php script, I will be able to get the data I need.

Correct me If I 'm wrong but I only need a list of the ordered products, not shipping, not tax, nothing like that.

So my question is can I get rid of many of these $optionsxxx arrays, and still achieve the same functionality?

    // save the session stuff permanently in case internationalcheckout loses the session
    $_SESSION['ppipn_key_to_remove'] = session_id();
    $db->Execute("delete from " . TABLE_INTERNATIONALCHECKOUT_SESSION . " where session_id = '" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "'");

    $sql = "insert into " . TABLE_INTERNATIONALCHECKOUT_SESSION . " (session_id, saved_session, expiry) values (
            '" . zen_db_input($_SESSION['ppipn_key_to_remove']) . "',
            '" . base64_encode(serialize($_SESSION)) . "',
            '" . (time() + (1*60*60*24*2)) . "')";

Regarding the SESSION Above it is needed by Zen Cart to work or it's just a requirement of Paypal?

    $db->Execute($sql);

    $my_currency = select_pp_currency();
    $this->transaction_currency = $my_currency;

    $this->transaction_amount = ($this->totalsum * $currencies->get_value($my_currency));

I keep the above

and comment out the below code snippet

/* Can I eliminate this section ???

    $telephone = preg_replace('/\D/', '', $order->customer['telephone']);
    if ($telephone != '') {
      $optionsPhone['H_PhoneNumber'] = $telephone;
      if (in_array($order->customer['country']['iso_code_2'], array('US','CA'))) {
        $optionsPhone['night_phone_a'] = substr($telephone,0,3);
        $optionsPhone['night_phone_b'] = substr($telephone,3,3);
        $optionsPhone['night_phone_c'] = substr($telephone,6,4);
        $optionsPhone['day_phone_a'] = substr($telephone,0,3);
        $optionsPhone['day_phone_b'] = substr($telephone,3,3);
        $optionsPhone['day_phone_c'] = substr($telephone,6,4);
    } else {
        $optionsPhone['night_phone_b'] = $telephone;
        $optionsPhone['day_phone_b'] = $telephone;
      }
    }

    $optionsCore = array(
                   'charset' => CHARSET,
                   'lc' => $order->customer['country']['iso_code_2'],
                   'page_style' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_PAGE_STYLE,
                   'custom' => zen_session_name() . '=' . zen_session_id(),
                   'business' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_BUSINESS_ID,
                   'return' => zen_href_link(FILENAME_CHECKOUT_PROCESS, 'referer=internationalcheckout', 'SSL'),
                   'cancel_return' => zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'),
                   'shopping_url' => zen_href_link(FILENAME_SHOPPING_CART, '', 'SSL'),
                   'notify_url' => zen_href_link('ipn_main_handler.php', '', 'SSL',false,false,true),
                   'redirect_cmd' => '_xclick',
                   'rm' => 2,
                   'bn' => 'zencart',
                   'mrb' => 'R-6C7952342H795591R',
                   'pal' => '9E82WJBKKGPLQ',
                   );
    $optionsCust = array(
                   'first_name' => replace_accents($order->customer['firstname']),
                   'last_name' => replace_accents($order->customer['lastname']),
                   'address1' => replace_accents($order->customer['street_address']),
                   'city' => replace_accents($order->customer['city']),
                   'state' => zen_get_zone_code($order->customer['country']['id'], $order->customer['zone_id'], $order->customer['zone_id']),
                   'zip' => $order->customer['postcode'],
                   'country' => $order->customer['country']['iso_code_2'],
                   'email' => $order->customer['email_address'],
                   );
    if ($order->customer['suburb'] != '') $optionsCust['address2'] = $order->customer['suburb'];
    if (MODULE_PAYMENT_INTERNATIONALCHECKOUT_ADDRESS_REQUIRED == 2) $optionsCust = array(
                   'address_name' => replace_accents($order->customer['firstname'] . ' ' . $order->customer['lastname']),
                   'address_street' => replace_accents($order->customer['street_address']),
                   'address_city' => replace_accents($order->customer['city']),
                   'address_state' => zen_get_zone_code($order->customer['country']['id'], $order->customer['zone_id'], $order->customer['zone_id']),
                   'address_zip' => $order->customer['postcode'],
                   'address_country' => $order->customer['country']['title'],
                   'address_country_code' => $order->customer['country']['iso_code_2'],
                   'payer_email' => $order->customer['email_address'],
                   );
    $optionsShip = array(
                   //'address_override' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_ADDRESS_OVERRIDE,
                   'no_shipping' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_ADDRESS_REQUIRED,
                   );*/

I understand the code below loops through the ordered products and get the info

    if (MODULE_PAYMENT_INTERNATIONALCHECKOUT_DETAILED_CART == 'Yes') $optionsLineItems = ipn_getLineItemDetails();
    if (sizeof($optionsLineItems) > 0) {
      $optionsLineItems['cmd'] = '_cart';
//      $optionsLineItems['num_cart_items'] = sizeof($order->products);
/* Not needed as I don't have to pass shipping nor handling data

      if (isset($optionsLineItems['shipping'])) {
        $optionsLineItems['shipping_1'] = $optionsLineItems['shipping'];
        unset($optionsLineItems['shipping']);
      }
      if (isset($optionsLineItems['handling'])) {
        $optionsLineItems['handling_1'] = $optionsLineItems['handling'];
        unset($optionsLineItems['handling']);
      }*/
      unset($optionsLineItems['subtotal']);
      // if line-item details couldn't be kept due to calculation mismatches or discounts etc, default to aggregate mode
      if (!isset($optionsLineItems['item_name_1'])) $optionsLineItems = array();
      //if ($optionsLineItems['amount'] != $this->transaction_amount) $optionsLineItems = array();
      /*ipn_debug_email('Line Item Details (if blank, this means there was a data mismatch, and thus bypassed): ' . "\n" . print_r($optionsLineItems, true));
    }*/

// Aggregate is it an Auxiliary array? Redundant?

    $optionsAggregate = array(
                   'cmd' => '_ext-enter',
                   'item_name' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_PURCHASE_DESCRIPTION_TITLE,
                   'item_number' => MODULE_PAYMENT_INTERNATIONALCHECKOUT_PURCHASE_DESCRIPTION_ITEMNUM,
                   //'num_cart_items' => sizeof($order->products),
                   'amount' => number_format($this->transaction_amount, $currencies->get_decimal_places($my_currency)),
                   'shipping' => '0.00',
                    );
    if (MODULE_PAYMENT_INTERNATIONALCHECKOUT_TAX_OVERRIDE == 'true') $optionsAggregate['tax'] = '0.00';
    if (MODULE_PAYMENT_INTERNATIONALCHECKOUT_TAX_OVERRIDE == 'true') $optionsAggregate['tax_cart'] = '0.00';

From here I think everything is needed, please note I only need to submit the detailed order and nothing else ...

$optionsTrans = array(
                'upload' => (int)(sizeof($order->products) > 0),
                'currency_code' => $my_currency,
//                   'internationalcheckout_order_id' => $internationalcheckout_order_id,
                //'no_note' => '1',
                //'invoice' => '',
                 );

 // if line-item info is invalid, use aggregate:
 if (sizeof($optionsLineItems) > 0) $optionsAggregate = $optionsLineItems;

 // prepare submission
 $options = array_merge($optionsCore, $optionsCust, $optionsPhone, $optionsShip, $optionsTrans, $optionsAggregate);
 ipn_debug_email('Keys for submission: ' . print_r($options, true));
 // build the button fields
 foreach ($options as $name => $value) {
   // remove quotation marks
   $value = str_replace('"', '', $value);
   // check for invalid chars
   if (preg_match('/[^a-zA-Z_0-9]/', $name)) {
     ipn_debug_email('datacheck - ABORTING - preg_match found invalid submission key: ' . $name . ' (' . $value . ')');
     break;
   }
   // do we need special handling for & and = symbols?
   //if (strpos($value, '&') !== false || strpos($value, '=') !== false) $value = urlencode($value);

   $buttonArray[] = zen_draw_hidden_field($name, $value);
 }
 $process_button_string = implode("\n", $buttonArray) . "\n";

 $_SESSION['internationalcheckout_transaction_info'] = array($this->transaction_amount, $this->transaction_currency);
 return $process_button_string;
}
/**
* Store transaction info to the order and process any results that come back from the payment gateway
*/
7 Jan 2010, 7:51 AM
#14
zamzom avatar

zamzom

New Zenner

Join Date:
Jun 2009
Location:
Europe
Posts:
60
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

in paypal.php

 $options = array_merge($optionsCore, $optionsCust, $optionsPhone, $optionsShip, $optionsTrans, $optionsAggregate);

is basically holding all the parameters that will be transfered to the payment gateway (later transferred to an HTTP POST function).

This is basically handled in:

foreach ($options as $name => $value) {
      // ....
      // some lines removed
      //

      $buttonArray[] = zen_draw_hidden_field($name, $value);
    }
    $process_button_string = implode("\n", $buttonArray) . "\n";

So send only the things that are required, with the correct post item names as your payment gateway requires.

I don't understand why you use html input command, do you expect your customers to enter that data from a form? I think those items knowledge must be available in your cart items data, and you need fetch/form them somehow from there (i don't know how).

Paypal.php module creates paypal session history and keeps it in the database. session_id in the following is a reference to that database item. If you follow the methods you will recognize that it will be removed from the database later on after successful payment. You can keep this (provided you change the database name from TABLE_PAYPAL_SESSION to yours, unless you want to screw up the paypal database :yes:)

$_SESSION['ppipn_key_to_remove'] = session_id(); 
13 Mar 2010, 8:04 PM
#15
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

Hi,

I was wondering if I can use a an iFrame or I have to use curl to emulate it to post data, in a payment module?

The iframe will connect to the processor's page and just pass POST data (cart info, products and quantities), there is no need to validate anything, just retrieve the info from the shopping cart and pass it to the other site and the transaction will be completed in there.

13 Mar 2010, 8:14 PM
#16
schoolboy avatar

schoolboy

Totally Zenned

Join Date:
Jun 2005
Location:
Cumbria, UK
Posts:
10,327
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

As you are not being sufficiently specific, I make the assumption that you are trying to run zencart (or parts of it) in an Iframe.

Generally speaking this is not a good idea. You may experience session issues, and secondly, many payment gateways reject transactions coming out of an iframe.

13 Mar 2010, 8:53 PM
#17
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

Sorry for being so vague, it's exactly the opposite!

Within Zen Cart:

I need to run an iFrame with a payment module that uses it to connect to the processor. In this case I only need to pass checkout data, shopping cart contents as POST variables, only product info, description, price, quantities, plus a new field because I need to add shipping cost to their warehouse nothing else ...

That's why I was worried about compatibility issues, if a use a pure iFrame, as their system is designed to display my user page within this iFrame, there the customer will fulfill all his info, whatever payment and shipping method they choose, and personal data.
All within this iFrame.

So my question was, will it work or I better pass these parameters and vars using curl?

13 Mar 2010, 8:56 PM
#18
schoolboy avatar

schoolboy

Totally Zenned

Join Date:
Jun 2005
Location:
Cumbria, UK
Posts:
10,327
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

That is an answer that's beyond my modest skills, I'm afraid... :D

13 Mar 2010, 9:24 PM
#19
drbyte avatar

drbyte

Sensei

Join Date:
Jan 2004
Posts:
63,513
Plugin Contributions:
176

Re: Create a new module for International Checkout payment module

Much more secure, and much simpler to code (no templating, no UI, no "view" components) if you just use CURL.

13 Mar 2010, 9:58 PM
#20
icecold avatar

icecold

Zen Follower

Join Date:
Jul 2008
Posts:
360
Plugin Contributions:
0

Re: Create a new module for International Checkout payment module

DrByte:

Much more secure, and much simpler to code (no templating, no UI, no "view" components) if you just use CURL.

Then I will got for it ...
Thanks!