Forums / Addon Payment Modules / My custom Hosted Payment Plugin

My custom Hosted Payment Plugin

Views: 1,760

Results 1 to 10 of 10
15 Mar 2016, 6:58 PM
#1
vishwanathk avatar

vishwanathk

New Zenner

Join Date:
Mar 2016
Location:
India
Posts:
6
Plugin Contributions:
0

My custom Hosted Payment Plugin

Hi All,

I have make a new hosted payment plugins in zencart but i am facing a problem that after clicking on the confirm order i am redirecting to the payment gateway site and and after making the payment order there i am return to my site on success page. I have a found the there is no new order is created in table and getting old order on success page.

I have found that order is creating only when checout_process.php file is used other wise no order is creating there in table.

So how i make this to create the order and make payment plugins.

Please help me

Thanks

15 Mar 2016, 7:32 PM
#2
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: My custom Hosted Payment Plugin

I don't recall each of the steps, but if you follow the code from includes/modules/pages/checkout_process there are actions that follow to include payment process checks. If all "steps" are successful, then the customer is eventually taken to checkout_success. Use of checkout_process is the correct way to go/continue.

ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...

16 Mar 2016, 12:42 AM
#3
drbyte avatar

drbyte

Sensei

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

Re: My custom Hosted Payment Plugin

The payment gateway must return you to your checkout_process page.

.
Zen Cart - putting the dream of business ownership within reach of anyone!
Donate to: DrByte directly or to the Zen Cart team as a whole

Remember: Any code suggestions you see here are merely suggestions. You assume full responsibility for your use of any such suggestions, including any impact ANY alterations you make to your site may have on your PCI compliance.
Furthermore, any advice you see here about PCI matters is merely an opinion, and should not be relied upon as "official". Official PCI information should be obtained from the PCI Security Council directly or from one of their authorized Assessors.

16 Mar 2016, 10:08 AM
#4
vishwanathk avatar

vishwanathk

New Zenner

Join Date:
Mar 2016
Location:
India
Posts:
6
Plugin Contributions:
0

Re: My custom Hosted Payment Plugin

Thanks for your reply , but getting this so i am pasting my plugins code here, please guide me where i am missing :

<?php /** * IPSP BIlling HPP payment module * * @package ipsp billing * @copyright Copyright 2016 IPSP Billing Team * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 * @version Author: Mario New in v1.0.0 */ /** * IPSP Billing HPP Payment module class */ class ipsp_billing_hpp extends base { /** * $code determines the internal 'code' name used to designate "this" payment module * * @var string */ var $code; /** * $moduleVersion is the plugin version number */ var $moduleVersion = '1.00'; /** * $title is the displayed name for this payment method * * @var string */ var $title; /** * $description is used to display instructions in the admin * * @var string */ var $description; /** * $enabled determines whether this module shows or not... in catalog. * * @var boolean */ var $enabled; /** * log file folder * * @var string */ private $_logDir = ''; /** * vars for internal processing and debug/logging */ private $reportable_submit_data; private $authorize; var $auth_code; var $transaction_id; /** * $order_status determines the status assigned to orders paid-for using this module */ var $order_status; /** * Constructor */ function __construct() { global $order; $this->code = 'ipsp_billing_hpp'; $this->title = MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_CATALOG_TITLE; // Payment module title in Catalog if (IS_ADMIN_FLAG === true) { $this->description = MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_DESCRIPTION; $this->title = MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_ADMIN_TITLE; // Payment module title in Admin if (MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS == 'True' && (MODULE_PAYMENT_IPSP_BILLING_HPP_AUTH_CODE == 'XXXXXXXXXXXXXXXX' || MODULE_PAYMENT_IPSP_BILLING_HPP_PAYMENT_GATEWAY_URL == 'http://gatewayurl.com')) { $this->title .= '<span class="alert"> (Not Configured)</span>'; } } $this->enabled = (MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS == 'True'); $this->sort_order = MODULE_PAYMENT_IPSP_BILLING_HPP_SORT_ORDER; if ((int) MODULE_PAYMENT_IPSP_BILLING_HPP_ORDER_STATUS_ID > 0) { $this->order_status = MODULE_PAYMENT_IPSP_BILLING_HPP_ORDER_STATUS_ID; } if (is_object($order)) $this->update_status(); $this->form_action_url = MODULE_PAYMENT_IPSP_BILLING_HPP_PAYMENT_GATEWAY_URL; $this->_logDir = defined('DIR_FS_LOGS') ? DIR_FS_LOGS : DIR_FS_SQL_CACHE; } /** * Calculate zone matches and flag settings to determine whether this module should display to customers or not */ function update_status() { global $order, $db; // other status checks? if ($this->enabled) { // other checks here } } /** * JS validation which does error-checking of data-entry if this module is selected for use * (Number, Owner Lengths) * * @return string */ function javascript_validation() { return ''; } /** * Display Credit Card Information Submission Fields on the Checkout Payment Page * * @return array */ function selection() { return array('id' => $this->code, 'module' => $this->title); } /** * Evaluates the Credit Card Type for acceptance and the validity of the Credit Card Number & Expiration Date * */ function pre_confirmation_check() { // no validation required since all the payment processing is hosted externally return true; } /** * Display Credit Card Information on the Checkout Confirmation Page * * @return array */ function confirmation() { return array(); } /** * Build the data and actions to process when the "Submit" button is pressed on the order-confirmation screen. * This sends the data to the payment gateway for processing. * (These are hidden fields on the checkout confirmation page) * * @return string */ function process_button() { global $db, $order, $order_totals; // Calculate the next expected order id $result = $db->Execute("select max(orders_id)+1 as orders_id from " . TABLE_ORDERS . " order by orders_id"); $next_order_id = $result->fields['orders_id']; // add randomized suffix to order id to produce uniqueness ... since it's unwise to submit the same order-number twice to the gateway, and this order is not yet committed $next_order_id = (string) $next_order_id . '-' . zen_create_random_value(6, 'chars'); $submit_data_core = array( 'acid' => MODULE_PAYMENT_IPSP_BILLING_HPP_ACC_ID, 'auth' => MODULE_PAYMENT_IPSP_BILLING_HPP_AUTH_CODE, 'successurl' => MODULE_PAYMENT_IPSP_BILLING_HPP_SUCCESSURL, 'amount' => number_format($order->info['total'], 2), 'currency' => $_SESSION['currency'], 'Reference' => $next_order_id, 'FirstName' => $order->billing['firstname'], 'LastName' => $order->billing['lastname'], 'Address' => $order->billing['street_address'], 'City' => $order->billing['city'], 'State' => $order->billing['state'], 'PostCode' => $order->billing['postcode'], 'Country' => $order->billing['country']['title'], 'Phone' => $order->customer['telephone'], 'Email' => $order->customer['email_address'], 'x_method' => 'CC', // if not passed, then the payment types can be configured in the PaymentPage including enabling PayPal and other features. ); // Add line-item data to transaction if (sizeof($order->products) < 100) { $items = ''; $delim = '<|>'; $product_code = $commodity_code = ''; // not submitted $item_log = array(); for ($i = 0; $i < sizeof($order->products); $i++) { $p = $order->products[$i]; $line = $p['name'].$delim; $items .= zen_draw_hidden_field('product', $line); $item_log[] = $line; } } $submit_data = array_merge($submit_data_core); $submit_data[zen_session_name()] = zen_session_id(); $process_button_string = "\n"; foreach ($submit_data as $key => $value) { $process_button_string .= zen_draw_hidden_field($key, $value) . "\n"; } $process_button_string .= $items . "\n"; // prepare a copy of submitted data for error-reporting purposes $this->reportable_submit_data = $submit_data; $this->reportable_submit_data['items'] = $item_log; $this->_debugActions($this->reportable_submit_data, 'Submit-Data', '', zen_session_id()); return $process_button_string; } /** * Store the CC info to the order and process any results that come back from the payment gateway * */ function before_process() { global $messageStack, $order; $this->authorize = $_REQUEST; $this->TransID = $this->authorize['transactionID']; $this->Reference = $this->authorize['referenceID']; $this->_debugActions($this->authorize, 'Response-Data', '', zen_session_id()); if ($this->authorize['transactionID'] != '') { $messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_DECLINED_MESSAGE , 'error'); zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false)); } // Code 3 or anything else is an error //$messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_ERROR_MESSAGE . ' ' . $this->authorize['x_response_reason_text'] . ' ' . $this->authorize['Bank_Message'], 'error'); $messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_HPP_TEXT_ERROR_MESSAGE, 'error'); zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false)); return false; } /** * Add receipt and transaction id to order-status-history (order comments) * * @return boolean */ function after_process() { global $insert_id, $db, $order, $currencies; $this->authorize = $_REQUEST; $this->TransID = $this->authorize['transactionID']; $this->Reference = $this->authorize['referenceID']; //$this->notify('MODULE_PAYMENT_IPSP_BILLING_HPP_POSTPROCESS_HOOK'); $sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, customer_notified, date_added) values (:orderComments, :orderID, :orderStatus, 1, now() )"; $sql = $db->bindVars($sql, ':orderComments', 'Tranasction Details. TransID: ' . $this->TransID . ' Reference: ' . $this->Reference, 'string'); $sql = $db->bindVars($sql, ':orderID', $insert_id, 'integer'); $sql = $db->bindVars($sql, ':orderStatus', $this->order_status, 'integer'); $db->Execute($sql); return false; } /** * Check to see whether module is installed * * @return boolean */ function check() { global $db; if (!isset($this->_check)) { $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS'"); $this->_check = $check_query->RecordCount(); } return $this->_check; } /** * Install the payment module and its configuration settings * */ function install() { global $db, $messageStack; if (defined('MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS')) { $messageStack->add_session('First Data Payment Pages module already installed.', 'error'); zen_redirect(zen_href_link(FILENAME_MODULES, 'set=payment&module=firstdata')); return 'failed'; } $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable IPSP Billing HPP Module', 'MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS', 'True', 'Check true to enable this payment method.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_IPSP_BILLING_HPP_SORT_ORDER', '0', 'Sort order of displaying payment options to the customer. Lowest is displayed first.', '6', '0', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_IPSP_BILLING_HPP_ORDER_STATUS_ID', '2', 'New order status to show in order.', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Account ID', 'MODULE_PAYMENT_IPSP_BILLING_HPP_ACC_ID', 'XXXXXXXX', 'This is your 8 digit account ID.', '6', '0', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Authentication Code', 'MODULE_PAYMENT_IPSP_BILLING_HPP_AUTH_CODE', 'XXXXXXXXXXXXXXXX', 'This is your 16 character authentication code.', '6', '0', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Payment gateway URL', 'MODULE_PAYMENT_IPSP_BILLING_HPP_PAYMENT_GATEWAY_URL', 'http://gatewayurl.com', 'The payment gateway URL.', '6', '0', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Success URL', 'MODULE_PAYMENT_IPSP_BILLING_HPP_SUCCESSURL', '" . zen_catalog_href_link('checkout_success', '', 'SSL') . '&' . "', 'Your site URL if the payment is success.', '6', '0', now())"); $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Log', 'MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING', 'True', 'Check true to enable log.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())"); } /** * Remove the module and all its settings * */ function remove() { global $db; $db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')"); } /** * Internal list of configuration keys used for configuration of the module * * @return array */ function keys() { return array('MODULE_PAYMENT_IPSP_BILLING_HPP_STATUS', 'MODULE_PAYMENT_IPSP_BILLING_HPP_SORT_ORDER', 'MODULE_PAYMENT_IPSP_BILLING_HPP_ORDER_STATUS_ID', 'MODULE_PAYMENT_IPSP_BILLING_HPP_ACC_ID', 'MODULE_PAYMENT_IPSP_BILLING_HPP_AUTH_CODE', 'MODULE_PAYMENT_IPSP_BILLING_HPP_PAYMENT_GATEWAY_URL', 'MODULE_PAYMENT_IPSP_BILLING_HPP_SUCCESSURL', 'MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING'); } /** * Used to do any debug logging / tracking / storage as required. */ function _debugActions($response, $mode, $order_time = '') { if ($order_time == '') $order_time = date("F j, Y, g:i a"); $response['url'] = $this->form_action_url; $this->reportable_submit_data['url'] = $this->form_action_url; if (isset($response['x_login'])) $response['x_login'] = '*******' . substr($response['x_login'], -8); if (isset($this->reportable_submit_data['x_login'])) $this->reportable_submit_data['x_login'] = '*******' . substr($response['x_login'], -8); $errorMessage = date('M-d-Y h:i:s') . "\n=================================\n\n"; if ($mode == 'Submit-Data') $errorMessage .= 'Sent to HPP Payments Page: ' . print_r($this->reportable_submit_data, true) . "\n\n"; if ($mode == 'Response-Data') $errorMessage .= 'Response Code: ' . $response['transactionID'] . ".\nResponse Text: " . $response['referenceID'] . "\n\n"; // store log file if log mode enabled if (stristr(MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING, 'True') || strstr(MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING, 'All')) { $key = date('Y-m-d'); $file = $this->_logDir . '/' . 'IPSP_Billing_' . $key . '.log'; $fp = @fopen($file, 'a'); @fwrite($fp, $errorMessage); @fclose($fp); } // send email alerts only if in alert mode or if email specifically requested as logging mode if ((isset($response['x_response_code']) && $response['x_response_code'] != '1' && stristr(MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING, 'Alerts')) || stristr(MODULE_PAYMENT_IPSP_BILLING_HPP_DEBUGGING, 'Email')) { zen_mail(STORE_NAME, STORE_OWNER_EMAIL_ADDRESS, 'First Data HostedPayments Alert ' . $response['x_invoice_num'] . ' ' . date('M-d-Y h:i:s') . ' ' . $response['x_trans_id'], $errorMessage, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, array('EMAIL_MESSAGE_HTML' => nl2br($errorMessage)), 'debug'); } } }
16 Mar 2016, 3:15 PM
#5
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: My custom Hosted Payment Plugin

Your before_process function does not properly operate. Take a look at other built in payment options and how they operate. In both of the redirect calls, the individual s sent back to checkout_payment. Also the last step in the function is never proceesed (return false).

Further to be sure, in order to not get caught in the first redirect, the transactionid is expected to be blank at this point?

ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...

16 Mar 2016, 3:21 PM
#6
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: My custom Hosted Payment Plugin

Oh, also, in the future when posting code, please press the # button in the message toolbar just before pasting so that the code will be within ```
[CODE] and [/CODE]

ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...

5 Apr 2016, 4:38 PM
#7
vishwanathk avatar

vishwanathk

New Zenner

Join Date:
Mar 2016
Location:
India
Posts:
6
Plugin Contributions:
0

Re: My custom Hosted Payment Plugin

Hi Friend , i got the solution of my problem. i had to send to cheout_process page with an action= parameter I can catch and then order is creating now. Thanks a lot to all....

11 Apr 2016, 5:46 PM
#8
vishwanathk avatar

vishwanathk

New Zenner

Join Date:
Mar 2016
Location:
India
Posts:
6
Plugin Contributions:
0

Re: My custom Hosted Payment Plugin

Hi,

I have made a payment module that we take customer credit card number on site and make process.
If 3ds is enabled form the admin then payment method send to ASC URL for the verification and then return back to TermURL .
I am a making a XML then calling the curl then upon response code for 116 we are making 3ds verification .

But i getting problem that how i can send to the ASC URL and make TermURL(also called callback URL) to make payment and create order successfully? Please help me.

Here is my current code :

<?php

/**
 * IPSP Billing DirectAPI payment module
 *
 * @package ipsp billing
 * @copyright Copyright 2016 IPSP Billing Team
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 * @version Author: Mario   New in v1.0.0
 */

/**
 * IPSP Billing DirectAPI Payment module class
 */
class ipsp_billing_directapi extends base {

    /**
     * $code determines the internal 'code' name used to designate "this" payment module
     *
     * @var string
     */
    var $code;

    /**
     * $moduleVersion is the plugin version number
     */
    var $moduleVersion = '1.0.0';

    /**
     * $title is the displayed name for this payment method
     *
     * @var string
     */
    var $title;

    /**
     * $description is admin-display details for this payment method
     *
     * @var string
     */
    var $description;

    /**
     * $enabled determines whether this module shows or not... in catalog.
     *
     * @var boolean
     */
    var $enabled;

    /**
     * $sort_order determines the display-order of this module to customers
     */
    var $sort_order;

    /**
     * $commError and $commErrNo are CURL communication error details for debug purposes
     */
    var $commError, $commErrNo;

    /**
     * transaction vars hold the IDs of the completed payment
     */
    var $transaction_id, $transaction_messages, $auth_code, $acs_URL, $responsecode;

    /**
     * internal vars
     */
    private $avs_codes, $cvv_codes;

    /**
     * Constructor
     */
    function __construct() {
        global $order;

        $this->code = 'ipsp_billing_directapi';
        $this->title = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CATALOG_TITLE; // Payment module title in Catalog
        if (IS_ADMIN_FLAG === true) {
            $this->title = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_ADMIN_TITLE;
            if (MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE == 'xxxxxxxxxxxxxxxx')
                $this->title .= '<span class="alert"> (not configured; API details needed)</span>';
            if (MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Sandbox')
                $this->title .= '<span class="alert"> (Sandbox mode)</span>';
            $new_version_details = plugin_version_check_for_updates(2050, $this->moduleVersion);
            if ($new_version_details !== false) {
                $this->title .= '<span class="alert">' . ' - NOTE: A NEW VERSION OF THIS PLUGIN IS AVAILABLE. <a href="' . $new_version_details['link'] . '" target="_blank">[Details]</a>' . '</span>';
            }
        }

        $this->description = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_DESCRIPTION;
        $this->enabled = ((MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS == 'True') ? true : false);
        $this->sort_order = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER;

        // determine order-status for transactions
        if ((int) MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID > 0) {
            $this->order_status = MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID;
        }
        if ($this->responsecode == '116' && MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Yes') {
            $this->form_action_url = $this->acs_URL;
        }

        $this->_logDir = DIR_FS_LOGS;
    }

    function update_status() {
        
    }

    function javascript_validation() {
        return '';
    }

    function selection() {
        global $order;

        for ($i = 1; $i < 13; $i++) {
            $expires_month[] = array('id' => sprintf('%02d', $i), 'text' => strftime('%B - (%m)', mktime(0, 0, 0, $i, 1, 2000)));
        }
        $today = getdate();
        for ($i = $today['year']; $i < $today['year'] + 15; $i++) {
            $expires_year[] = array('id' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)));
        }

        // helper for auto-selecting the radio-button next to this module so the user doesn't have to make that choice
        $onFocus = ' onfocus="methodSelect(\'pmt-' . $this->code . '\')"';

        $selection = array(
            'id' => $this->code,
            'module' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CATALOG_TITLE,
            'fields' => array(
                array(
                    'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_NUMBER,
                    'field' => zen_draw_input_field($this->code . '_cc_number', '', 'payeezy-data="cc_number" id="' . $this->code . '_cc-number"' . $onFocus . ' autocomplete="off"'),
                    'tag' => $this->code . '_cc-number'
                ),
                array(
                    'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_EXPIRES,
                    'field' => zen_draw_pull_down_menu($this->code . '_cc_expires_month', $expires_month, strftime('%m'), 'payeezy-data="exp_month" id="' . $this->code . '_cc-expires-month"' . $onFocus) . ' ' .
                    zen_draw_pull_down_menu($this->code . '_cc_expires_year', $expires_year, '', 'payeezy-data="exp_year" id="' . $this->code . '_cc-expires-year"' . $onFocus),
                    'tag' => $this->code . '_cc-expires-month'
                ),
                array(
                    'title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CVV,
                    'field' => zen_draw_input_field($this->code . '_cc_cvv', '', 'size="4" maxlength="4"' . 'payeezy-data="cvv_code" id="' . $this->code . '_cc-cvv"' . $onFocus . ' autocomplete="off"'),
                    'tag' => $this->code . '_cc-cvv'
                ),
            )
        );
        return $selection;
    }

    function pre_confirmation_check() {
        global $messageStack;
        if (!isset($_POST[$this->code . '_cc_number']) || trim($_POST[$this->code . '_cc_number']) == '' || !isset($_POST[$this->code . '_cc_cvv']) || trim($_POST[$this->code . '_cc_cvv']) == '') {
            $messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_MISSING_FDTOKEN, 'error');
            zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
        }
    }

    function confirmation() {
        $confirmation = array('fields' => array(
                array('title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_NUMBER,
                    'field' => zen_output_string_protected($_POST[$this->code . '_cc_number'])),
                array('title' => MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TEXT_CREDIT_CARD_EXPIRES,
                    'field' => strftime('%B, %Y', mktime(0, 0, 0, $_POST[$this->code . '_cc_expires_month'], 1, $_POST[$this->code . '_cc_expires_year']))),
        ));
        return $confirmation;
    }

    function process_button() {
        $process_button_string = zen_draw_hidden_field('cc_number', zen_output_string_protected($_POST[$this->code . '_cc_number']));
        $process_button_string .= zen_draw_hidden_field('cc_expires_month', (int) $_POST[$this->code . '_cc_expires_month']);
        $process_button_string .= zen_draw_hidden_field('cc_expires_year', (int) $_POST[$this->code . '_cc_expires_year']);
        $process_button_string .= zen_draw_hidden_field('cc_cvv', zen_output_string_protected($_POST[$this->code . '_cc_cvv']));
        return $process_button_string;
    }

    function before_process() {
        global $db, $messageStack, $order, $currencies;

        // Calculate the next expected order id
        $result = $db->Execute("select max(orders_id)+1 as orders_id from " . TABLE_ORDERS . " order by orders_id");
        $next_order_id = $result->fields['orders_id'];
        // add randomized suffix to order id to produce uniqueness ... since it's unwise to submit the same order-number twice to the gateway, and this order is not yet committed
        $next_order_id = (string) $next_order_id . '-' . zen_create_random_value(6, 'chars');
        //$customer_ip = $_SERVER["REMOTE_ADDR"];

        $xml = '<?xml version="1.0" encoding="utf-8"?>
			<Request type="AuthorizeCapture">
				 <AccountID>' . MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID . '</AccountID>
				 <AccountAuth>' . MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE . '</AccountAuth>
				 <Transaction>
					 <Reference>' . $next_order_id . '</Reference>
					 <Amount>' . number_format($order->info['total'], 2) . '</Amount>
					 <Currency>' . strtoupper($order->info['currency']) . '</Currency>
					 <Email>' . $order->customer['email_address'] . '</Email>
					 <IPAddress>' . '175.45.134.67' . '</IPAddress>
					 <Phone>' . $order->customer['telephone'] . '</Phone>
					 <FirstName>' . $order->billing['firstname'] . '</FirstName>
					 <LastName>' . $order->billing['lastname'] . '</LastName>
					 <Address>' . $order->billing['street_address'] . '</Address>
					 <City>' . $order->billing['city'] . '</City>
					 <State>' . $order->billing['state'] . '</State>
					 <PostCode>' . $order->billing['postcode'] . '</PostCode>
					 <Country>' . $order->billing['country']['iso_code_2'] . '</Country>
					 <CardNumber>' . $_POST['cc_number'] . '</CardNumber>
					 <CardExpMonth>' . $_POST['cc_expires_month'] . '</CardExpMonth>
					 <CardExpYear>' . $_POST['cc_expires_year'] . '</CardExpYear>
					 <CardCVV>' . $_POST['cc_cvv'] . '</CardCVV>
				 </Transaction>
			</Request>';
        $this->logTransactionData($xml);
        $result = $this->send_request(MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL, $xml);
        $this->logTransactionData($result);
        $response = $this->get_responsestatus($result);
        // log the response data
        $this->logTransactionData($response);

        if ($response === FALSE) {
            $messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_DECLINED, 'error');
            zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
        } else {
            if ($response['responsecode'] == '100' || $response['responsecode'] == '110') {
                $this->transaction_id = $response['txid'];
                $this->transaction_messages = $response['msg'];
                return true;
            } elseif ($response['responsecode'] == '116' && MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS == 'Yes') {
                $ACSURL = $response['ACSURL'];
                $PaReq = $response['PaReq'];
                $MD = $response['MD'];
                $html = '<html><head><title>Three DS Verification</title></head><body>';
                $html.= '<form action='.$ACSURL.' method="post" id="threeds_direct">'
                        . '<input type="hidden" name="PaReq" value='.$PaReq.'>'
                        . '<input type="hidden" name="MD" value='.$MD.'>'
                        . '<input type="hidden" name="TermUrl" value="http://magento1.chetu.local/index.php?main_page=checkout_payment/">'
                        . '</form>';
                $html.= '<div style="text-align:center;">You will be redirected for 3DS verification. Please do not refresh page!!!<br/><br/>
<img  title="Loading next step..." alt="Loading next step..." ></div>';
                $html.= '<script type="text/javascript">document.getElementById("threeds_direct").submit();</script></body></html>';
                echo $html;

                //zen_redirect(zen_href_link($response['ACSURL'], '', 'SSL', true, false));
            } else {
                $messageStack->add_session('checkout_payment', MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ERROR_PAYMNET_GATEWAY, 'error');
                zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL', true, false));
            }
        }
    }

    /**
     * Post-process activities. Updates the order-status history data with the auth code from the transaction.
     *
     * @return boolean
     */
    function after_process() {
        global $insert_id, $db, $order;
        $sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, customer_notified, date_added) values (:orderComments, :orderID, :orderStatus, 1, now() )";
        $sql = $db->bindVars($sql, ':orderComments', 'Credit Card payment.  TransID: ' . $this->transaction_id . ' - ' . $this->transaction_messages, 'string');
        $sql = $db->bindVars($sql, ':orderID', $insert_id, 'integer');
        $sql = $db->bindVars($sql, ':orderStatus', $this->order_status, 'integer');
        $db->Execute($sql);
        return false;
    }

    function check() {
        global $db;
        if (!isset($this->_check)) {
            $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS'");
            $this->_check = $check_query->RecordCount();
        }
        return $this->_check;
    }

    function install() {
        global $db;

        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable IPSP Billing DirectAPI Module', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS', 'True', 'Check true to enable this payment method.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER', '0', 'Sort order of displaying payment options to the customer. Lowest is displayed first.', '6', '0', now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID', '2', 'Set the status of orders made with this payment module to this value', '6', '0', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Account ID', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID', 'xxxxxxxx', 'This is your 8 digit account ID.', '6', '0',  now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Authentication Code', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE', 'xxxxxxxxxxxxxxxx', 'This is your 16 character authentication code.', '6', '0',  now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Payment gateway URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL', '', 'The payment gateway URL.', '6', '0',  now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Notification URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_NOTIFICATION_URL', '', 'Notification URL for payment status.', '6', '0',  now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable 3DS', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS', 'No', 'For 3DS only', '6', '0', 'zen_cfg_select_option(array(\'Yes\', \'No\'), ', now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Term URL', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TERM_URL', '', 'For 3DS only.', '6', '0',  now())");
        $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable log', 'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING', 'True', 'Check true to enable log.', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
    }

    function remove() {
        global $db;
        $db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
        return array(
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_STATUS',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_SORT_ORDER',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ORDER_STATUS_ID',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ACC_ID',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_AUTH_CODE',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_GATEWAY_URL',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_NOTIFICATION_URL',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_ENABLE_3DS',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_TERM_URL',
            'MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING',
        );
    }

    private function send_request($url, $xml) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

        $result = curl_exec($ch);
        curl_close($ch);

        return $result;
    }

    private function get_responsestatus($result) {
        $xmlresult = simplexml_load_string($result);

        // Simple display of the end result
        if (isset($xmlresult->ResponseCode)) {
            $status['responsecode'] = $xmlresult->ResponseCode;
        }
        if (isset($xmlresult->Description)) {
            $status['msg'] = $xmlresult->Description;
        }
        if (isset($xmlresult->Reference)) {
            $status['reference'] = $xmlresult->Reference;
        }
        if (isset($xmlresult->TransactionID)) {
            $status['txid'] = $xmlresult->TransactionID;
        }
        if (isset($xmlresult->ProcessingTime)) {
            $status['processingtime'] = $xmlresult->ProcessingTime;
        }
        if (isset($xmlresult->StatusCode)) {
            $status['statuscode'] = $xmlresult->StatusCode;
        }
        if (isset($xmlresult->StatusDescription)) {
            $status['statusdescription'] = $xmlresult->StatusDescription;
        }
        if (isset($xmlresult->ThreeDS->ACSURL)) {
            $status['ACSURL'] = $xmlresult->ThreeDS->ACSURL;
        }
        if (isset($xmlresult->ThreeDS->PaReq)) {
            $status['PaReq'] = $xmlresult->ThreeDS->PaReq;
        }
        if (isset($xmlresult->ThreeDS->MD)) {
            $status['MD'] = $xmlresult->ThreeDS->MD;
        }
        if (isset($xmlresult->RefTrxID)) {
            $status['RefTrxID'] = $xmlresult->RefTrxID;
        }

        if (isset($status['responsecode'])) {
            return $status;
        } else {
            return FALSE;
        }
    }

    /**
     * Log transaction errors if enabled
     */
    private function logTransactionData($response) {
        global $db;

        $logMessage = date('M-d-Y h:i:s') .
                "\n=================================\n\n" .
                '' . $response . "\n";

        if (strstr(MODULE_PAYMENT_IPSP_BILLING_DIRECTAPI_LOGGING, 'True')) {
            $todayDate = date('Y-m-d');
            $file = $this->_logDir . '/' . 'IPSP_Billing_' . $todayDate . '.log';
            if ($fp = @fopen($file, 'a')) {
                fwrite($fp, $logMessage);
                fclose($fp);
            }
        }
    }

}
12 Apr 2016, 6:01 PM
#9
vishwanathk avatar

vishwanathk

New Zenner

Join Date:
Mar 2016
Location:
India
Posts:
6
Plugin Contributions:
0

Re: My custom Hosted Payment Plugin

Hi,

I have made a payment method that is required to do 3ds verification for that it will go to the third party URL(i.e. ASC url) upon successful verification it will come to the user site with some data in URL. Now on this page we will again make curl request and get some response. From this response we will make some condition depending on the true condition we will send it to the success URL and if condition is false then it will go to the failure page.

So how i make file that is accessible and do this whole process on this page.

Please help me.

Thanks,
Vishwanath

14 Apr 2016, 10:07 PM
#10
kobra avatar

kobra

Black Belt

Join Date:
Aug 2005
Location:
Arizona
Posts:
31,500
Plugin Contributions:
4

Re: My custom Hosted Payment Plugin

Have a look at /includes/modules/payment/authorizenet_aim.php
/includes/modules/payment/authorizenet/authorizenet_admin_notification.php
/includes/languages/english/modules/payment/authorizenet_aim.php

This is the complete package that you can use as a guide

Zen-Venom Get Bitten