Jump to content

Edit History

Makatserchyk

Makatserchyk

Hello!

I am getting this error when I'm trying to install the module in PS 1.6.1.7:

 

[PrestaShop] Fatal error in module file :/home/gymvisua/public_html/modules/twocheckout/twocheckout.php:
syntax error, unexpected '?'

twocheckout (parse error in /modules/twocheckout/twocheckout.php)

twocheckout (class missing in /modules/twocheckout/twocheckout.php)

 

Please help!

 

<?php

use PrestaShop\PrestaShop\Core\Payment\PaymentOption;

require_once 'libs/interfaces/interface-2co-arrayable.php';
require_once 'libs/interfaces/interface-2co-jsonable.php';
require_once 'libs/abstract/abstract-2co-entity.php';

require_once 'libs/class-twocheckout-settings.php';

require_once 'libs/includes/class-mobile-detect.php';
require_once 'libs/includes/class-twocheckout-checkout.php';
require_once 'libs/includes/class-twocheckout-customer.php';
require_once 'libs/includes/class-twocheckout-helper.php';
require_once 'libs/includes/class-twocheckout-logger.php';
require_once 'libs/includes/class-twocheckout-refund.php';

require_once 'TwoCheckoutApi.php';

if ( ! defined( '_PS_VERSION_' ) ) {
    exit;
}

/**
 * Class Twocheckout - safe payment method
 */
class Twocheckout extends \PaymentModule {
    const DEBUG_MODE = false;
    const REFUND_REASON = 'Other';
    public $tcoApi;
    public $details;
    public $owner;
    public $name;
    public $address;
    public $bootstrap;
    public $is_eu_compatible;
    public $extra_mail_vars;
    public $confirmUninstall;
    public $tco_settings;
    public $logger;
    protected $_html = '';
    protected $_postErrors = [];
    /**
     * @var
     */
    private $module;

    /**
     * @var array
     */
    private $_signParams = [
        'return-url',
        'return-type',
        'expiration',
        'order-ext-ref',
        'item-ext-ref',
        'lock',
        'cust-params',
        'customer-ref',
        'customer-ext-ref',
        'currency',
        'prod',
        'price',
        'qty',
        'tangible',
        'type',
        'opt',
        'coupon',
        'description',
        'recurrence',
        'duration',
        'renewal-price',
    ];

    /**
     * Twocheckout constructor.
     */
    public function __construct() {
        $this->name                   = 'twocheckout';
        $this->tab                    = 'payments_gateways';
        $this->version                = '1.2.0';
        $this->ps_versions_compliancy = [ 'min' => '1.7', 'max' => _PS_VERSION_ ];
        $this->author                 = '2Checkout by Verifone';
        $this->controllers            = [ 'validation' ];
        $this->is_eu_compatible       = 1;
        $this->currencies             = true;
        $this->currencies_mode        = 'checkbox';

        $this->logger       = new Twocheckout_Logger( __FILE__ );
        $this->tcoApi       = new TwoCheckoutApi();
        $this->tco_settings = new Twocheckout_Settings();
        $this->tcoApi->setSecretKey( $this->tco_settings->getSecretKey() );
        $this->tcoApi->setSellerId( $this->tco_settings->getSid() );
        $this->tcoApi->setSecretWord( $this->tco_settings->getSecretWord() );

        $this->bootstrap = true;
        parent::__construct();

        $this->displayName = $this->l( '2checkout' );
        $this->description = $this->l( '2checkout - Simple & safe payment solutions' );

        if ( ! count( Currency::checkPaymentCurrencies( $this->id ) ) ) {
            $this->warning = $this->l( 'No currency has been set for this module.' );
        }
        $this->confirmUninstall = $this->l( 'Are you sure you want to uninstall 2Checkout payment modules?' );
    }

    /**
     * default style for API form
     * @return string
     */
    private function getDefaultStyle() {
        return '{
                    "margin": "0",
                    "fontFamily": "Helvetica, sans-serif",
                    "fontSize": "1rem",
                    "fontWeight": "400",
                    "lineHeight": "1.5",
                    "color": "#212529",
                    "textAlign": "left",
                    "backgroundColor": "#FFFFFF",
                    "*": {
                        "boxSizing": "border-box"
                    },
                    ".no-gutters": {
                        "marginRight": 0,
                        "marginLeft": 0
                    },
                    ".row": {
                        "display": "flex",
                        "flexWrap": "wrap"
                    },
                    ".col": {
                        "flexBasis": "0",
                        "flexGrow": "1",
                        "maxWidth": "100%",
                        "padding": "0",
                        "position": "relative",
                        "width": "100%"
                    },
                    "div": {
                        "display": "block"
                    },
                    ".field-container": {
                        "paddingBottom": "14px"
                    },
                    ".field-wrapper": {
                        "paddingRight": "25px"
                    },
                    ".input-wrapper": {
                        "position": "relative"
                    },
                    "label": {
                        "display": "inline-block",
                        "marginBottom": "9px",
                        "color": "#313131",
                        "fontSize": "14px",
                        "fontWeight": "300",
                        "lineHeight": "17px"
                    },
                    "input": {
                        "overflow": "visible",
                        "margin": 0,
                        "fontFamily": "inherit",
                        "display": "block",
                        "width": "100%",
                        "height": "42px",
                        "padding": "10px 12px",
                        "fontSize": "18px",
                        "fontWeight": "400",
                        "lineHeight": "22px",
                        "color": "#313131",
                        "backgroundColor": "#FFF",
                        "backgroundClip": "padding-box",
                        "border": "1px solid #CBCBCB",
                        "borderRadius": "3px",
                        "transition": "border-color .15s ease-in-out,box-shadow .15s ease-in-out",
                        "outline": 0
                    },
                    "input:focus": {
                        "border": "1px solid #5D5D5D",
                        "backgroundColor": "#FFFDF2"
                    },
                    ".is-error input": {
                        "border": "1px solid #D9534F"
                    },
                    ".is-error input:focus": {
                        "backgroundColor": "#D9534F0B"
                    },
                    ".is-valid input": {
                        "border": "1px solid #1BB43F"
                    },
                    ".is-valid input:focus": {
                        "backgroundColor": "#1BB43F0B"
                    },
                    ".validation-message": {
                        "color": "#D9534F",
                        "fontSize": "10px",
                        "fontStyle": "italic",
                        "marginTop": "6px",
                        "marginBottom": "-5px",
                        "display": "block",
                        "lineHeight": "1"
                    },
                    ".card-expiration-date": {
                        "paddingRight": ".5rem"
                    },
                    ".is-empty input": {
                        "color": "#EBEBEB"
                    },
                    ".lock-icon": {
                        "top": "calc(50% - 7px)",
                        "right": "10px"
                    },
                    ".valid-icon": {
                        "top": "calc(50% - 8px)",
                        "right": "-25px"
                    },
                    ".error-icon": {
                        "top": "calc(50% - 8px)",
                        "right": "-25px"
                    },
                    ".card-icon": {
                        "top": "calc(50% - 10px)",
                        "left": "10px",
                        "display": "none"
                    },
                    ".is-empty .card-icon": {
                        "display": "block"
                    },
                    ".is-focused .card-icon": {
                        "display": "none"
                    },
                    ".card-type-icon": {
                        "right": "30px",
                        "display": "block"
                    },
                    ".card-type-icon.visa": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.mastercard": {
                        "top": "calc(50% - 14.5px)"
                    },
                    ".card-type-icon.amex": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.discover": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.jcb": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.dankort": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.cartebleue": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.diners": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.elo": {
                        "top": "calc(50% - 14px)"
                    }
                }';
    }

    /**
     * install the module
     * @return bool|string
     */
    public function install() {

        if ( parent::install()
             && $this->registerHook( 'displayHeader' )
             && $this->registerHook( 'paymentOptions' )
             && $this->registerHook( 'displayOrderConfirmation' )
             && $this->registerHook( 'actionProductCancel' )
             && $this->registerHook( 'displayBackOfficeHeader' )
             && $this->registerHook( 'displayAdminOrder' )
             && $this->registerHook( 'displayAdminOrderTop' )
        ) {

            Configuration::updateValue( 'TWOCHECKOUT_STYLE', $this->getDefaultStyle() ); // to have a starting point
            Configuration::updateValue( 'TWOCHECKOUT_IPN_URL',
                $this->context->link->getModuleLink( 'twocheckout', 'ipn' ) );

            return true;
        }

        return false;
    }

    /**
     * uninstall the module and deletes the config keys
     * @return bool
     */
    function uninstall() {
        Configuration::deleteByName( 'TWOCHECKOUT_SID' );
        Configuration::deleteByName( 'TWOCHECKOUT_SECRET_KEY' );
        Configuration::deleteByName( 'TWOCHECKOUT_DEMO' );
        Configuration::deleteByName( 'TWOCHECKOUT_TYPE' );
        Configuration::deleteByName( 'TWOCHECKOUT_IPN_URL' );
        Configuration::deleteByName( 'TWOCHECKOUT_SECRET_WORD' );
        Configuration::deleteByName( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' );
        Configuration::deleteByName( 'TWOCHECKOUT_STYLE' );

        return $this->unregisterHook( 'displayHeader' )
               && $this->unregisterHook( 'paymentOptions' )
               && $this->unregisterHook( 'displayOrderConfirmation' )
               && $this->unregisterHook( 'actionProductCancel' )
               && $this->unregisterHook( 'displayBackOfficeHeader' )
               && $this->unregisterHook( 'displayAdminOrder' )
               && $this->unregisterHook( 'displayAdminOrderTop' )
               && parent::uninstall();
    }

    /**
     * show the settings page, also saves and validates the form on submit
     * @return string
     */
    public function getContent() {
        $output = null;

        if ( Tools::isSubmit( 'submit' . $this->name ) ) {
            $merchantId        = strval( Tools::getValue( 'TWOCHECKOUT_SID' ) );
            $buyLinkSecretWord = strval( Tools::getValue( 'TWOCHECKOUT_SECRET_WORD' ) );
            $secretKey         = strval( Tools::getValue( 'TWOCHECKOUT_SECRET_KEY' ) );
            $inline            = strval( Tools::getValue( 'TWOCHECKOUT_TYPE' ) );
            $demoMode          = strval( Tools::getValue( 'TWOCHECKOUT_DEMO' ) );
            $style             = strval( Tools::getValue( 'TWOCHECKOUT_STYLE' ) );
            $styleMode         = strval( Tools::getValue( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' ) );

            if (
                ( ! $merchantId || empty( $merchantId ) || ! Validate::isGenericName( $merchantId ) )
                && ( ! $buyLinkSecretWord || empty( $buyLinkSecretWord ) || ! Validate::isGenericName( $buyLinkSecretWord ) )
                && ( ! $secretKey || empty( $secretKey ) || ! Validate::isGenericName( $secretKey ) )
                && ( ! $inline || empty( $inline ) || ! Validate::isGenericName( $inline ) )
                && ( ! $demoMode || empty( $demoMode ) || ! Validate::isGenericName( $demoMode ) )
            ) {
                $output .= $this->displayError( $this->l( 'Invalid Configuration value' ) );
            } else {
                Configuration::updateValue( 'TWOCHECKOUT_SID', $merchantId );
                Configuration::updateValue( 'TWOCHECKOUT_SECRET_WORD', $buyLinkSecretWord );
                Configuration::updateValue( 'TWOCHECKOUT_SECRET_KEY', $secretKey );
                Configuration::updateValue( 'TWOCHECKOUT_TYPE', $inline );
                Configuration::updateValue( 'TWOCHECKOUT_DEMO', $demoMode );
                Configuration::updateValue( 'TWOCHECKOUT_STYLE_DEFAULT_MODE', $styleMode );
                Configuration::updateValue( 'TWOCHECKOUT_STYLE', $style );
                $output .= $this->displayConfirmation( $this->l( 'Settings updated' ) );
            }
        }

        return $output . $this->displayForm();
    }

    /**
     * creates the form for the module settings (admin area)
     * @return string
     */
    private function displayForm() {
        // Get default language
        $defaultLang = (int) Configuration::get( 'PS_LANG_DEFAULT' );

        // Init Fields form array
        $fieldsForm[0]['form'] = [
            'legend' => [
                'title' => $this->l( 'Settings' ),
            ],
            'input'  => [
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Seller ID(Merchant Code)' ),
                    'name'     => 'TWOCHECKOUT_SID',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Buy Link Secret Word' ),
                    'name'     => 'TWOCHECKOUT_SECRET_WORD',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Secret Key' ),
                    'name'     => 'TWOCHECKOUT_SECRET_KEY',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'IPN Url' ),
                    'name'     => 'TWOCHECKOUT_IPN_URL',
                    'size'     => 200,
                    'value'    => $this->context->link->getModuleLink( 'twocheckout', 'ipn' ),
                    'desc'     => $this->l( 'Copy this link to your 2checkout account under the IPN section' ),
                    'readonly' => true,
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Cart type' ),
                    'name'     => 'TWOCHECKOUT_TYPE',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'api',
                            'value' => 2,
                            'label' => $this->l( 'API' ),
                        ],
                        [
                            'id'    => 'yes',
                            'value' => 0,
                            'label' => $this->l( 'Convert Plus' ),
                        ],
                        [
                            'id'    => 'no',
                            'value' => 1,
                            'label' => $this->l( 'Inline' ),
                        ]
                    ],
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Demo Mode' ),
                    'name'     => 'TWOCHECKOUT_DEMO',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'yes',
                            'value' => 1,
                            'label' => $this->l( 'Yes' ),
                        ],
                        [
                            'id'    => 'no',
                            'value' => 0,
                            'label' => $this->l( 'No' ),
                        ]
                    ],
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Use default style for API' ),
                    'name'     => 'TWOCHECKOUT_STYLE_DEFAULT_MODE',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'YES',
                            'value' => 1,
                            'label' => $this->l( 'YES, use default' ),
                        ],
                        [
                            'id'    => 'NO',
                            'value' => 0,
                            'label' => $this->l( 'NO, use my custom style' ),
                        ]
                    ],
                ],
                [
                    'type'  => 'textarea',
                    'label' => $this->l( 'Custom style for API form' ),
                    'name'  => 'TWOCHECKOUT_STYLE',
                    'desc'  => $this->l( 'IMPORTANT! This is the styling object that styles your form.
                     Do not remove or add new classes. You can modify the existing ones. Use
                      double quotes for all keys and values! - VALID JSON FORMAT REQUIRED (validate 
                      json before save here: https://jsonlint.com/ ).' )
                ],
            ],
            'submit' => [
                'title' => $this->l( 'Update settings' ),
                'class' => 'btn btn-default pull-right',
            ],
        ];

        $helper = new HelperForm();

        // Module, token and currentIndex
        $helper->module          = $this;
        $helper->name_controller = $this->name;
        $helper->token           = Tools::getAdminTokenLite( 'AdminModules' );
        $helper->currentIndex    = AdminController::$currentIndex . '&configure=' . $this->name;

        // Language
        $helper->default_form_language    = $defaultLang;
        $helper->allow_employee_form_lang = $defaultLang;

        // Title and toolbar
        $helper->title          = $this->displayName;
        $helper->show_toolbar   = true;
        $helper->toolbar_scroll = true;
        $helper->submit_action  = 'submit' . $this->name;
        $helper->toolbar_btn    = [
            'save' => [
                'desc' => $this->l( 'Save' ),
                'href' => AdminController::$currentIndex . '&configure=' . $this->name . '&save' . $this->name .
                          '&token=' . Tools::getAdminTokenLite( 'AdminModules' ),
            ],
            'back' => [
                'href' => AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite( 'AdminModules' ),
                'desc' => $this->l( 'Back to list' ),
            ],
        ];

        // Load current value
        $helper->fields_value['TWOCHECKOUT_SID']                = Configuration::get( 'TWOCHECKOUT_SID' );
        $helper->fields_value['TWOCHECKOUT_SECRET_WORD']        = Configuration::get( 'TWOCHECKOUT_SECRET_WORD' );
        $helper->fields_value['TWOCHECKOUT_SECRET_KEY']         = Configuration::get( 'TWOCHECKOUT_SECRET_KEY' );
        $helper->fields_value['TWOCHECKOUT_TYPE']               = Configuration::get( 'TWOCHECKOUT_TYPE' );
        $helper->fields_value['TWOCHECKOUT_DEMO']               = Configuration::get( 'TWOCHECKOUT_DEMO' );
        $helper->fields_value['TWOCHECKOUT_IPN_URL']            = Configuration::get( 'TWOCHECKOUT_IPN_URL' );
        $helper->fields_value['TWOCHECKOUT_STYLE']              = Configuration::get( 'TWOCHECKOUT_STYLE' );
        $helper->fields_value['TWOCHECKOUT_STYLE_DEFAULT_MODE'] = Configuration::get( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' );

        return $helper->generateForm( $fieldsForm );
    }

    /**
     * @param $params
     *
     * @return mixed
     */

    public function hookHeader( $params ) {
        $returnContent = '';

        $allValues = Tools::getAllValues();
        $resources = [];
        $link      = '';

        if ( Tools::getValue( 'controller' ) == "order" ) {
            if ( ! $this->checkActiveModule() ) {
                return;
            }
            $cart = isset( $params['cart'] ) ? $params['cart'] : $this->context->cart;

            if ( $this->tco_settings->getPaymentType() == 1 ) {
                //load scripts for INLINE
                $this->context->controller->registerJavascript( $this->name . '-gen-url-context',
                    'modules/' . $this->name . '/views/assets/js/inline_validate.js'
                );
                Media::addJsDef( array(
                    'reloadWhenInlineClose' => version_compare( _PS_VERSION_, '1.7.7', '>=' )
                ) );
                $resources[] = _PS_BASE_URL_ . __PS_BASE_URI__ . 'modules/' . $this->name . '/views/assets/js/inline_validate.js' . '?v=' . $this->version;

            } elseif ( $this->tco_settings->getPaymentType() == 2 ) {
                //No script needed to load for this.

            } else {
                //load convert plus scripts
                $this->context->controller->registerJavascript( $this->name . '-gen-url-context',
                    'modules/' . $this->name . '/views/assets/js/cp_validate.js'
                );
                $resources[] = _PS_BASE_URL_ . __PS_BASE_URI__ . 'modules/' . $this->name . '/views/assets/js/cp_validate.js' . '?v=' . $this->version;
            }

            if ( ! empty( $resources ) ) {
                $link = $this->context->link->getModuleLink( $this->name, 'generateUrl',
                    [ 'module_name' => $this->name, 'cart_id' => $cart->id ], true );
                Media::addJsDef( array(
                    'tco_verify_url' => $link
                ) );
                $this->context->smarty->assign( 'resources', $resources );
            }

            $returnContent .= $this->context->smarty->fetch( 'module:' . $this->name . '/views/templates/front/prefetch.tpl' );
        }

        return $returnContent;
    }

    public function hookDisplayOrderConfirmation( $params ) {
        if ( ( ! isset( $params['order'] ) || $params['order']->module != $this->name ) || ! $this->active ) {
            return false;
        }

        $order = $params['order'] ?? null;
        $cart  = $params['cart'] ?? null;
        $this->smarty->assign( [ 'order' => $order, 'cart' => $cart ] );

        return $this->fetch( 'module:twocheckout/views/templates/hook/payment_return.tpl' );
    }

    /**
     * @param $params
     *
     * @return PaymentOption[]|void|void[]
     */
    public function hookPaymentOptions( $params ) {
        if ( ! $this->active || ! $this->checkCurrency( $params['cart'] ) ) {
            return;
        }
        // we clear the cache for every change we make
        Tools::clearSmartyCache();
        Tools::clearXMLCache();
        Media::clearCache();
        Tools::generateIndex();

        if ( Configuration::get( 'TWOCHECKOUT_TYPE' ) == 2 ) { // api with 2payJs
            return [ $this->getApiPaymentOption( $params['cart'] ) ];
        } elseif ( Configuration::get( 'TWOCHECKOUT_TYPE' ) == 1 ) { // inline
            return [ $this->getInlinePaymentOption() ];
        } else { // Convert+
            return [ $this->getConvertPaymentOption() ];
        }
    }

    /**
     * @param $orderReturn
     */
    public function hookActionProductCancel( $params ) {
        $apiResponse = [];
        $order       = isset( $params['order'] ) ? $params['order'] : null;
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {
            if ( $order->getCurrentOrderState()->id != Configuration::get( 'PS_OS_REFUND' ) ) {
                $orderPayment = OrderPayment::getByOrderReference( $order->reference );
                $Refno        = null;
                foreach ( $orderPayment as $payment ) {
                    $invoice = $payment->getOrderInvoice( $order->id );
                    if ( $invoice ) {
                        $Refno = trim( $payment->transaction_id );
                    }
                }

                //Prepare comment and get only the 150 accepted characters.
                $refundCommentStr = Tools::getValue( 'tco-refund-comment', '' );
                $refundComment    = trim( substr( $refundCommentStr, 0, 150 ) );
                $refundReason     = self::REFUND_REASON;

                if ( ! empty( $Refno ) ) {
                    $orderData = $this->tcoApi->call( "orders/" . $Refno . "/", [], 'GET' );
                    if ( $order->total_paid == $orderData["GrossPrice"] ) {
                        // Refund Details
                        $refundDetails = [
                            "amount"  => $order->total_paid,
                            "comment" => $refundComment,
                            "reason"  => $refundReason
                        ];
                    } else {
                        $lineItems = $orderData["Items"];
                        usort( $lineItems, "cmpPrices" );
                        $lineitemReference = $lineItems[0]["LineItemReference"];
                        if ( $lineItems[0]['Price']['GrossPrice'] >= $params['amount'] ) {
                            // Refund Item Details
                            $itemsArray[] = [
                                "Quantity"          => "1",
                                "LineItemReference" => $lineitemReference,
                                "Amount"            => $order->total_paid
                            ];

                            // Refund Details
                            $refundDetails = [
                                "amount"  => $order->total_paid,
                                "comment" => $refundComment,
                                "reason"  => $refundReason,
                                "items"   => $itemsArray
                            ];
                        } else {
                            return [
                                'status'  => 'error',
                                'rawdata' => 'Partial refund amount cannot exceed the highest priced item. Please login to your 2Checkout admin to issue the partial refund manually.',
                                'transid' => $Refno,
                            ];
                        }
                    }

                    if ( ! empty( $Refno ) ) {
                        $apiResponse = $this->tcoApi->call( 'orders/' . $Refno . '/refund/', $refundDetails, 'POST' );
                    }
                }

                if ( isset( $apiResponse['error_code'] ) ) {
                    error_log( sprintf(
                        'Error Refunding Invoice with error code: "%s"',
                        isset( $apiResponse['error_code'] ) ? $apiResponse['error_code'] : 'An unknown error occurred'
                    ), 0 );

                    $error_msg = $this->l( 'Error Refunding Invoice for order "' . $order->reference . '" with transaction id "'
                                           . $Refno . '". Message: ' . $apiResponse['message'] . ' ' );

                    $this->context->controller->errors['2co_refund_error'] = $error_msg;
                } else {
                    $order->setCurrentState( Configuration::get( 'PS_OS_REFUND' ) );
                }
            }
        }
    }

    public function hookDisplayAdminOrderTop( $params ) {
        $id_order = isset( $params['id_order'] ) ? $params['id_order'] : null;
        $order    = new Order( (int) $id_order );
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {
            $errors = $this->getAdminOrderPage2CoRefundErrors( $params );

            if ( ! empty( $errors ) ) {
                $this->context->controller->errors[] = $errors;
            }

            $return = $this->disablePartialRefund();
            $return .= $this->getRefundCommentBox();
            $return .= $this->getTotalItemsForRefund( $order );

            return $return;
        }
    }

    public function hookDisplayAdminOrder( $params ) {
        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return false;
        }
        $id_order = isset( $params['id_order'] ) ? $params['id_order'] : null;
        $order    = new Order( (int) $id_order );
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {

            $errors = $this->getAdminOrderPage2CoRefundErrors( $params );

            if ( ! empty( $errors ) ) {
                $this->context->controller->errors[] = $errors;
            }
            $return = $this->disablePartialRefund();
            $return .= $this->getRefundCommentBox();
            $return .= $this->getTotalItemsForRefund( $order );

            return $return;
        }
    }

    private function getRefundCommentBox() {
        $this->context->smarty->assign(
            [
                'tco_refund_comment_box'    => $this->trans( 'Refund Comment...' ),
                'tco_refund_max_length_str' => $this->trans( '*Max 150 characters.' ),
                'tco_refund_max_length'     => 150
            ] );

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundCommentBox17x.tpl' );

        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundCommentBox.tpl' );
    }

    private function getTotalItemsForRefund( $order ) {
        $products    = $order->getProducts();
        $prods_array = [];
        foreach ( $products as $prod_id => $params ) {
            $prods_array[ $prod_id ] = $params['product_quantity'];
        }
        $notAllProductsAlert = $this->getTranslator()->trans( 'Please select all products!' );
        $hasPaidShipping     = $this->hasPaidShipping( $order->getShipping() );
        $shippingMsgAlert    = $this->getTranslator()->trans( 'Order does not have free shipping. Please include that in full refund!' );
        $this->context->smarty->assign(
            [
                'tco_refund_products_list' => json_encode( $prods_array ),
                'not_all_products_alert'   => $notAllProductsAlert,
                'has_paid_shipping'        => $hasPaidShipping,
                'shipping_msg_alert'       => $shippingMsgAlert
            ] );

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundItemsCorrection17x.tpl' );
        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundItemsCorrection.tpl' );
    }

    private function getAdminOrderPage2CoRefundErrors( $params ) {
        $twocheckout_msg = '';
        if ( isset( $this->context->controller->errors['2co_refund_error'] ) ) {
            $twocheckout_msg = $this->context->controller->errors['2co_refund_error'];
        }

        return $twocheckout_msg;
    }

    private function disablePartialRefund() {

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/disablePartialRefund17x.tpl' );
        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/disablePartialRefund.tpl' );
    }

    /**
     * @param $cart
     *
     * @return bool
     */
    public function checkCurrency( $cart ) {
        $currency_order    = new Currency( $cart->id_currency );
        $currencies_module = $this->getCurrency( $cart->id_currency );

        if ( is_array( $currencies_module ) ) {
            foreach ( $currencies_module as $currency_module ) {
                if ( $currency_order->id == $currency_module['id_currency'] ) {
                    return true;
                }
            }
        }

        return false;
    }


    /**
     * @return PaymentOption|void
     */
    public function getInlinePaymentOption() {
        if ( ! $this->active ) {
            return;
        }
        $newOption = new PaymentOption();
        $newOption->setCallToActionText( 'Pay with 2Checkout' )
                  ->setAction( 'javascript:TwocheckoutInlineCheckout()' );

        return $newOption;
    }

    /**
     * @return PaymentOption|void
     */
    public function getConvertPaymentOption() {
        if ( ! $this->active ) {
            return;
        }
        $newOption = new PaymentOption();
        $newOption->setCallToActionText( 'Pay with 2Checkout' )
                  ->setAction( 'javascript:TwocheckoutCPCheckout()' );

        return $newOption;
    }

    /**
     * 2payJS->API payment method
     * @return PaymentOption
     * @throws SmartyException
     */
    public function getApiPaymentOption( $cart ) {
        if ( ! $this->active ) {
            return;
        }
        $newApiOption = new PaymentOption();
        $newApiOption->setCallToActionText($this->l('Pay with 2Checkout'))
                     ->setAction('javascript:Twocheckout2PayJs()')
                     ->setBinary(true)
                     ->setForm($this->generateApiForm($cart));

        return $newApiOption;
    }

    /**
     * genereates the form for the payment option (2payJs)
     * @return string
     * @throws SmartyException
     */
    protected function generateApiForm( $cart ) {

        // get style and remove newlines
        if ( Configuration::get( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' ) ) {
            $style = trim( preg_replace( '/\s\s+/', ' ', $this->getDefaultStyle() ) );
        } else {
            $style = trim( preg_replace( '/\s\s+/', ' ', Configuration::get( 'TWOCHECKOUT_STYLE' ) ) );
        }
        $this->context->smarty->assign( [
            'action'   => $this->context->link->getModuleLink( $this->name, 'generateUrl',
                [ 'module_name' => $this->name, 'cart_id' => $cart->id ], true ),
            'sellerId' => Configuration::get( 'TWOCHECKOUT_SID' ),
            'style'    => $style,
            'script'   => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/js/twocheckout.js' ),
            'css'      => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/css/twocheckout.css' ),
            'spinner'  => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/images/spinner.gif' ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/front/payment_form.tpl' );
    }

    /**
     * generates the form for the payment option (convert+ & inline)
     * @return string
     * @throws SmartyException
     */
    protected function generateInlineForm() {
        $this->context->smarty->assign( [
            'action' => $this->context->link->getModuleLink( $this->name, 'validation', [], true ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/inline_payment_options.tpl' );
    }

    /**
     * generates the form for the payment option (convert+ & inline)
     * @return string
     * @throws SmartyException
     */
    protected function generateForm() {
        $this->context->smarty->assign( [
            'action' => $this->context->link->getModuleLink( $this->name, 'validation', [], true ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/payment_options.tpl' );
    }


    /**
     * @param      $params
     * @param      $secretWord
     * @param bool $fromResponse
     *
     * @return string
     */
    public function generateSignature(
        $params,
        $secretWord,
        $fromResponse = false
    ) {

        if ( ! $fromResponse ) {
            $signParams = array_filter( $params, function ( $k ) {
                return in_array( $k, $this->_signParams );
            }, ARRAY_FILTER_USE_KEY );
        } else {
            $signParams = $params;
            if ( isset( $signParams['signature'] ) ) {
                unset( $signParams['signature'] );
            }
        }

        ksort( $signParams ); // order by key
        // Generate Hash
        $string = '';
        foreach ( $signParams as $key => $value ) {
            $string .= strlen( $value ) . $value;
        }

        return bin2hex( hash_hmac( 'sha256', $string, $secretWord, true ) );
    }


    /**
     * @param        $delivery
     * @param string $stateCode
     * @param string $countryIsoCode
     * @param string $email
     *
     * @return array
     */
    public function getBillingDetails( $delivery, string $stateCode, string $countryIsoCode, string $email = '' ) {

        $address = [
            'Address1'    => $delivery->address1,
            'City'        => $delivery->city,
            'State'       => $stateCode,
            'CountryCode' => $countryIsoCode,
            'Email'       => $email,
            'FirstName'   => $delivery->firstname,
            'LastName'    => $delivery->lastname,
            'Phone'       => $delivery->phone,
            'Zip'         => $delivery->postcode,
            'Company'     => $delivery->company,
            'FiscalCode'  => $delivery->vat_number
        ];

        if ( $delivery->address2 ) {
            $address['Address2'] = $delivery->address2;
        }

        return $address;
    }

    /**
     * for safety reasons we only send one Item with the grand total and the Cart_id as ProductName (identifier)
     * sending products order as ONE we dont have to calculate the total fee of the order (product price, tax, discounts etc)
     *
     * @param int $cart_id
     * @param float $total
     *
     * @return array
     */
    public function getItem( int $cart_id, float $total ) {
        $items[] = [
            'Code'             => null,
            'Quantity'         => 1,
            'Name'             => 'Cart_' . $cart_id,
            'Description'      => 'N/A',
            'RecurringOptions' => null,
            'IsDynamic'        => true,
            'Tangible'         => false,
            'PurchaseType'     => 'PRODUCT',
            'Price'            => [
                'Amount' => number_format( $total, 2, '.', '' ),
                'Type'   => 'CUSTOM'
            ]
        ];

        return $items;
    }

    /**
     * @param string $token
     * @param string $currency
     * @param int $cartId
     * @param int $orderId
     *
     * @return array
     */
    public function getPaymentDetails( string $token, string $currency, int $cartId ) {
        return [
            'Type'          => Configuration::get( 'TWOCHECKOUT_DEMO' ) == 1 ? 'TEST' : 'EES_TOKEN_PAYMENT',
            'Currency'      => strtolower( $currency ),
            'CustomerIP'    => $this->getCustomerIp(),
            'PaymentMethod' => [
                'EesToken'           => $token,
                'Vendor3DSReturnURL' => $this->context->link->getModuleLink( 'twocheckout', 'redirect3ds',
                    [ 'action' => 'success', 'cart' => $cartId ], true ),
                'Vendor3DSCancelURL' => $this->context->link->getModuleLink( 'twocheckout', 'redirect3ds',
                    [ 'action' => 'cancel', 'cart' => $cartId ], true )
            ]
        ];
    }

    /**
     * @param $has3ds
     *
     * @return string|null
     */
    public function hasAuthorize3DS( $has3ds ) {
        if ( isset( $has3ds ) && isset( $has3ds['Href'] ) && ! empty( $has3ds['Href'] ) ) {

            return $has3ds['Href'] . '?avng8apitoken=' . $has3ds['Params']['avng8apitoken'];
        }

        return null;
    }

    /**
     * get customer ip or returns a default ip
     * @return mixed|string
     */
    public function getCustomerIp() {
        if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
            //ip from share internet
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            //ip pass from proxy
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) === false ) {
            return $ip;
        }

        return '1.0.0.1';
    }

    public function checkActiveModule() {
        $active  = false;
        $modules = Hook::getHookModuleExecList( 'paymentOptions' );
        if ( empty( $modules ) ) {
            return;
        }
        foreach ( $modules as $module ) {
            if ( $module['module'] == $this->name ) {
                $active = true;
            }
        }

        return $active;
    }

    public function hasPaidShipping( $shippingArr ) {
        $total = 0;
        foreach ( $shippingArr as $shipping => $valuesArr ) {
            $total += $valuesArr['shipping_cost_tax_incl'];
        }

        return $total > 0;
    }

Makatserchyk

Makatserchyk

Hello!

I am getting this error when I'm trying to install the module in PS 1.6.1.7:

 

twocheckout (parse error in /modules/twocheckout/twocheckout.php)

twocheckout (class missing in /modules/twocheckout/twocheckout.php)

 

Please help!

 

<?php

use PrestaShop\PrestaShop\Core\Payment\PaymentOption;

require_once 'libs/interfaces/interface-2co-arrayable.php';
require_once 'libs/interfaces/interface-2co-jsonable.php';
require_once 'libs/abstract/abstract-2co-entity.php';

require_once 'libs/class-twocheckout-settings.php';

require_once 'libs/includes/class-mobile-detect.php';
require_once 'libs/includes/class-twocheckout-checkout.php';
require_once 'libs/includes/class-twocheckout-customer.php';
require_once 'libs/includes/class-twocheckout-helper.php';
require_once 'libs/includes/class-twocheckout-logger.php';
require_once 'libs/includes/class-twocheckout-refund.php';

require_once 'TwoCheckoutApi.php';

if ( ! defined( '_PS_VERSION_' ) ) {
    exit;
}

/**
 * Class Twocheckout - safe payment method
 */
class Twocheckout extends \PaymentModule {
    const DEBUG_MODE = false;
    const REFUND_REASON = 'Other';
    public $tcoApi;
    public $details;
    public $owner;
    public $name;
    public $address;
    public $bootstrap;
    public $is_eu_compatible;
    public $extra_mail_vars;
    public $confirmUninstall;
    public $tco_settings;
    public $logger;
    protected $_html = '';
    protected $_postErrors = [];
    /**
     * @var
     */
    private $module;

    /**
     * @var array
     */
    private $_signParams = [
        'return-url',
        'return-type',
        'expiration',
        'order-ext-ref',
        'item-ext-ref',
        'lock',
        'cust-params',
        'customer-ref',
        'customer-ext-ref',
        'currency',
        'prod',
        'price',
        'qty',
        'tangible',
        'type',
        'opt',
        'coupon',
        'description',
        'recurrence',
        'duration',
        'renewal-price',
    ];

    /**
     * Twocheckout constructor.
     */
    public function __construct() {
        $this->name                   = 'twocheckout';
        $this->tab                    = 'payments_gateways';
        $this->version                = '1.2.0';
        $this->ps_versions_compliancy = [ 'min' => '1.7', 'max' => _PS_VERSION_ ];
        $this->author                 = '2Checkout by Verifone';
        $this->controllers            = [ 'validation' ];
        $this->is_eu_compatible       = 1;
        $this->currencies             = true;
        $this->currencies_mode        = 'checkbox';

        $this->logger       = new Twocheckout_Logger( __FILE__ );
        $this->tcoApi       = new TwoCheckoutApi();
        $this->tco_settings = new Twocheckout_Settings();
        $this->tcoApi->setSecretKey( $this->tco_settings->getSecretKey() );
        $this->tcoApi->setSellerId( $this->tco_settings->getSid() );
        $this->tcoApi->setSecretWord( $this->tco_settings->getSecretWord() );

        $this->bootstrap = true;
        parent::__construct();

        $this->displayName = $this->l( '2checkout' );
        $this->description = $this->l( '2checkout - Simple & safe payment solutions' );

        if ( ! count( Currency::checkPaymentCurrencies( $this->id ) ) ) {
            $this->warning = $this->l( 'No currency has been set for this module.' );
        }
        $this->confirmUninstall = $this->l( 'Are you sure you want to uninstall 2Checkout payment modules?' );
    }

    /**
     * default style for API form
     * @return string
     */
    private function getDefaultStyle() {
        return '{
                    "margin": "0",
                    "fontFamily": "Helvetica, sans-serif",
                    "fontSize": "1rem",
                    "fontWeight": "400",
                    "lineHeight": "1.5",
                    "color": "#212529",
                    "textAlign": "left",
                    "backgroundColor": "#FFFFFF",
                    "*": {
                        "boxSizing": "border-box"
                    },
                    ".no-gutters": {
                        "marginRight": 0,
                        "marginLeft": 0
                    },
                    ".row": {
                        "display": "flex",
                        "flexWrap": "wrap"
                    },
                    ".col": {
                        "flexBasis": "0",
                        "flexGrow": "1",
                        "maxWidth": "100%",
                        "padding": "0",
                        "position": "relative",
                        "width": "100%"
                    },
                    "div": {
                        "display": "block"
                    },
                    ".field-container": {
                        "paddingBottom": "14px"
                    },
                    ".field-wrapper": {
                        "paddingRight": "25px"
                    },
                    ".input-wrapper": {
                        "position": "relative"
                    },
                    "label": {
                        "display": "inline-block",
                        "marginBottom": "9px",
                        "color": "#313131",
                        "fontSize": "14px",
                        "fontWeight": "300",
                        "lineHeight": "17px"
                    },
                    "input": {
                        "overflow": "visible",
                        "margin": 0,
                        "fontFamily": "inherit",
                        "display": "block",
                        "width": "100%",
                        "height": "42px",
                        "padding": "10px 12px",
                        "fontSize": "18px",
                        "fontWeight": "400",
                        "lineHeight": "22px",
                        "color": "#313131",
                        "backgroundColor": "#FFF",
                        "backgroundClip": "padding-box",
                        "border": "1px solid #CBCBCB",
                        "borderRadius": "3px",
                        "transition": "border-color .15s ease-in-out,box-shadow .15s ease-in-out",
                        "outline": 0
                    },
                    "input:focus": {
                        "border": "1px solid #5D5D5D",
                        "backgroundColor": "#FFFDF2"
                    },
                    ".is-error input": {
                        "border": "1px solid #D9534F"
                    },
                    ".is-error input:focus": {
                        "backgroundColor": "#D9534F0B"
                    },
                    ".is-valid input": {
                        "border": "1px solid #1BB43F"
                    },
                    ".is-valid input:focus": {
                        "backgroundColor": "#1BB43F0B"
                    },
                    ".validation-message": {
                        "color": "#D9534F",
                        "fontSize": "10px",
                        "fontStyle": "italic",
                        "marginTop": "6px",
                        "marginBottom": "-5px",
                        "display": "block",
                        "lineHeight": "1"
                    },
                    ".card-expiration-date": {
                        "paddingRight": ".5rem"
                    },
                    ".is-empty input": {
                        "color": "#EBEBEB"
                    },
                    ".lock-icon": {
                        "top": "calc(50% - 7px)",
                        "right": "10px"
                    },
                    ".valid-icon": {
                        "top": "calc(50% - 8px)",
                        "right": "-25px"
                    },
                    ".error-icon": {
                        "top": "calc(50% - 8px)",
                        "right": "-25px"
                    },
                    ".card-icon": {
                        "top": "calc(50% - 10px)",
                        "left": "10px",
                        "display": "none"
                    },
                    ".is-empty .card-icon": {
                        "display": "block"
                    },
                    ".is-focused .card-icon": {
                        "display": "none"
                    },
                    ".card-type-icon": {
                        "right": "30px",
                        "display": "block"
                    },
                    ".card-type-icon.visa": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.mastercard": {
                        "top": "calc(50% - 14.5px)"
                    },
                    ".card-type-icon.amex": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.discover": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.jcb": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.dankort": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.cartebleue": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.diners": {
                        "top": "calc(50% - 14px)"
                    },
                    ".card-type-icon.elo": {
                        "top": "calc(50% - 14px)"
                    }
                }';
    }

    /**
     * install the module
     * @return bool|string
     */
    public function install() {

        if ( parent::install()
             && $this->registerHook( 'displayHeader' )
             && $this->registerHook( 'paymentOptions' )
             && $this->registerHook( 'displayOrderConfirmation' )
             && $this->registerHook( 'actionProductCancel' )
             && $this->registerHook( 'displayBackOfficeHeader' )
             && $this->registerHook( 'displayAdminOrder' )
             && $this->registerHook( 'displayAdminOrderTop' )
        ) {

            Configuration::updateValue( 'TWOCHECKOUT_STYLE', $this->getDefaultStyle() ); // to have a starting point
            Configuration::updateValue( 'TWOCHECKOUT_IPN_URL',
                $this->context->link->getModuleLink( 'twocheckout', 'ipn' ) );

            return true;
        }

        return false;
    }

    /**
     * uninstall the module and deletes the config keys
     * @return bool
     */
    function uninstall() {
        Configuration::deleteByName( 'TWOCHECKOUT_SID' );
        Configuration::deleteByName( 'TWOCHECKOUT_SECRET_KEY' );
        Configuration::deleteByName( 'TWOCHECKOUT_DEMO' );
        Configuration::deleteByName( 'TWOCHECKOUT_TYPE' );
        Configuration::deleteByName( 'TWOCHECKOUT_IPN_URL' );
        Configuration::deleteByName( 'TWOCHECKOUT_SECRET_WORD' );
        Configuration::deleteByName( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' );
        Configuration::deleteByName( 'TWOCHECKOUT_STYLE' );

        return $this->unregisterHook( 'displayHeader' )
               && $this->unregisterHook( 'paymentOptions' )
               && $this->unregisterHook( 'displayOrderConfirmation' )
               && $this->unregisterHook( 'actionProductCancel' )
               && $this->unregisterHook( 'displayBackOfficeHeader' )
               && $this->unregisterHook( 'displayAdminOrder' )
               && $this->unregisterHook( 'displayAdminOrderTop' )
               && parent::uninstall();
    }

    /**
     * show the settings page, also saves and validates the form on submit
     * @return string
     */
    public function getContent() {
        $output = null;

        if ( Tools::isSubmit( 'submit' . $this->name ) ) {
            $merchantId        = strval( Tools::getValue( 'TWOCHECKOUT_SID' ) );
            $buyLinkSecretWord = strval( Tools::getValue( 'TWOCHECKOUT_SECRET_WORD' ) );
            $secretKey         = strval( Tools::getValue( 'TWOCHECKOUT_SECRET_KEY' ) );
            $inline            = strval( Tools::getValue( 'TWOCHECKOUT_TYPE' ) );
            $demoMode          = strval( Tools::getValue( 'TWOCHECKOUT_DEMO' ) );
            $style             = strval( Tools::getValue( 'TWOCHECKOUT_STYLE' ) );
            $styleMode         = strval( Tools::getValue( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' ) );

            if (
                ( ! $merchantId || empty( $merchantId ) || ! Validate::isGenericName( $merchantId ) )
                && ( ! $buyLinkSecretWord || empty( $buyLinkSecretWord ) || ! Validate::isGenericName( $buyLinkSecretWord ) )
                && ( ! $secretKey || empty( $secretKey ) || ! Validate::isGenericName( $secretKey ) )
                && ( ! $inline || empty( $inline ) || ! Validate::isGenericName( $inline ) )
                && ( ! $demoMode || empty( $demoMode ) || ! Validate::isGenericName( $demoMode ) )
            ) {
                $output .= $this->displayError( $this->l( 'Invalid Configuration value' ) );
            } else {
                Configuration::updateValue( 'TWOCHECKOUT_SID', $merchantId );
                Configuration::updateValue( 'TWOCHECKOUT_SECRET_WORD', $buyLinkSecretWord );
                Configuration::updateValue( 'TWOCHECKOUT_SECRET_KEY', $secretKey );
                Configuration::updateValue( 'TWOCHECKOUT_TYPE', $inline );
                Configuration::updateValue( 'TWOCHECKOUT_DEMO', $demoMode );
                Configuration::updateValue( 'TWOCHECKOUT_STYLE_DEFAULT_MODE', $styleMode );
                Configuration::updateValue( 'TWOCHECKOUT_STYLE', $style );
                $output .= $this->displayConfirmation( $this->l( 'Settings updated' ) );
            }
        }

        return $output . $this->displayForm();
    }

    /**
     * creates the form for the module settings (admin area)
     * @return string
     */
    private function displayForm() {
        // Get default language
        $defaultLang = (int) Configuration::get( 'PS_LANG_DEFAULT' );

        // Init Fields form array
        $fieldsForm[0]['form'] = [
            'legend' => [
                'title' => $this->l( 'Settings' ),
            ],
            'input'  => [
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Seller ID(Merchant Code)' ),
                    'name'     => 'TWOCHECKOUT_SID',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Buy Link Secret Word' ),
                    'name'     => 'TWOCHECKOUT_SECRET_WORD',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'Secret Key' ),
                    'name'     => 'TWOCHECKOUT_SECRET_KEY',
                    'size'     => 200,
                    'required' => true,
                ],
                [
                    'type'     => 'text',
                    'label'    => $this->l( 'IPN Url' ),
                    'name'     => 'TWOCHECKOUT_IPN_URL',
                    'size'     => 200,
                    'value'    => $this->context->link->getModuleLink( 'twocheckout', 'ipn' ),
                    'desc'     => $this->l( 'Copy this link to your 2checkout account under the IPN section' ),
                    'readonly' => true,
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Cart type' ),
                    'name'     => 'TWOCHECKOUT_TYPE',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'api',
                            'value' => 2,
                            'label' => $this->l( 'API' ),
                        ],
                        [
                            'id'    => 'yes',
                            'value' => 0,
                            'label' => $this->l( 'Convert Plus' ),
                        ],
                        [
                            'id'    => 'no',
                            'value' => 1,
                            'label' => $this->l( 'Inline' ),
                        ]
                    ],
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Demo Mode' ),
                    'name'     => 'TWOCHECKOUT_DEMO',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'yes',
                            'value' => 1,
                            'label' => $this->l( 'Yes' ),
                        ],
                        [
                            'id'    => 'no',
                            'value' => 0,
                            'label' => $this->l( 'No' ),
                        ]
                    ],
                ],
                [
                    'type'     => 'radio',
                    'label'    => $this->l( 'Use default style for API' ),
                    'name'     => 'TWOCHECKOUT_STYLE_DEFAULT_MODE',
                    'class'    => 't',
                    'required' => true,
                    'is_bool'  => true,
                    'values'   => [
                        [
                            'id'    => 'YES',
                            'value' => 1,
                            'label' => $this->l( 'YES, use default' ),
                        ],
                        [
                            'id'    => 'NO',
                            'value' => 0,
                            'label' => $this->l( 'NO, use my custom style' ),
                        ]
                    ],
                ],
                [
                    'type'  => 'textarea',
                    'label' => $this->l( 'Custom style for API form' ),
                    'name'  => 'TWOCHECKOUT_STYLE',
                    'desc'  => $this->l( 'IMPORTANT! This is the styling object that styles your form.
                     Do not remove or add new classes. You can modify the existing ones. Use
                      double quotes for all keys and values! - VALID JSON FORMAT REQUIRED (validate 
                      json before save here: https://jsonlint.com/ ).' )
                ],
            ],
            'submit' => [
                'title' => $this->l( 'Update settings' ),
                'class' => 'btn btn-default pull-right',
            ],
        ];

        $helper = new HelperForm();

        // Module, token and currentIndex
        $helper->module          = $this;
        $helper->name_controller = $this->name;
        $helper->token           = Tools::getAdminTokenLite( 'AdminModules' );
        $helper->currentIndex    = AdminController::$currentIndex . '&configure=' . $this->name;

        // Language
        $helper->default_form_language    = $defaultLang;
        $helper->allow_employee_form_lang = $defaultLang;

        // Title and toolbar
        $helper->title          = $this->displayName;
        $helper->show_toolbar   = true;
        $helper->toolbar_scroll = true;
        $helper->submit_action  = 'submit' . $this->name;
        $helper->toolbar_btn    = [
            'save' => [
                'desc' => $this->l( 'Save' ),
                'href' => AdminController::$currentIndex . '&configure=' . $this->name . '&save' . $this->name .
                          '&token=' . Tools::getAdminTokenLite( 'AdminModules' ),
            ],
            'back' => [
                'href' => AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite( 'AdminModules' ),
                'desc' => $this->l( 'Back to list' ),
            ],
        ];

        // Load current value
        $helper->fields_value['TWOCHECKOUT_SID']                = Configuration::get( 'TWOCHECKOUT_SID' );
        $helper->fields_value['TWOCHECKOUT_SECRET_WORD']        = Configuration::get( 'TWOCHECKOUT_SECRET_WORD' );
        $helper->fields_value['TWOCHECKOUT_SECRET_KEY']         = Configuration::get( 'TWOCHECKOUT_SECRET_KEY' );
        $helper->fields_value['TWOCHECKOUT_TYPE']               = Configuration::get( 'TWOCHECKOUT_TYPE' );
        $helper->fields_value['TWOCHECKOUT_DEMO']               = Configuration::get( 'TWOCHECKOUT_DEMO' );
        $helper->fields_value['TWOCHECKOUT_IPN_URL']            = Configuration::get( 'TWOCHECKOUT_IPN_URL' );
        $helper->fields_value['TWOCHECKOUT_STYLE']              = Configuration::get( 'TWOCHECKOUT_STYLE' );
        $helper->fields_value['TWOCHECKOUT_STYLE_DEFAULT_MODE'] = Configuration::get( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' );

        return $helper->generateForm( $fieldsForm );
    }

    /**
     * @param $params
     *
     * @return mixed
     */

    public function hookHeader( $params ) {
        $returnContent = '';

        $allValues = Tools::getAllValues();
        $resources = [];
        $link      = '';

        if ( Tools::getValue( 'controller' ) == "order" ) {
            if ( ! $this->checkActiveModule() ) {
                return;
            }
            $cart = isset( $params['cart'] ) ? $params['cart'] : $this->context->cart;

            if ( $this->tco_settings->getPaymentType() == 1 ) {
                //load scripts for INLINE
                $this->context->controller->registerJavascript( $this->name . '-gen-url-context',
                    'modules/' . $this->name . '/views/assets/js/inline_validate.js'
                );
                Media::addJsDef( array(
                    'reloadWhenInlineClose' => version_compare( _PS_VERSION_, '1.7.7', '>=' )
                ) );
                $resources[] = _PS_BASE_URL_ . __PS_BASE_URI__ . 'modules/' . $this->name . '/views/assets/js/inline_validate.js' . '?v=' . $this->version;

            } elseif ( $this->tco_settings->getPaymentType() == 2 ) {
                //No script needed to load for this.

            } else {
                //load convert plus scripts
                $this->context->controller->registerJavascript( $this->name . '-gen-url-context',
                    'modules/' . $this->name . '/views/assets/js/cp_validate.js'
                );
                $resources[] = _PS_BASE_URL_ . __PS_BASE_URI__ . 'modules/' . $this->name . '/views/assets/js/cp_validate.js' . '?v=' . $this->version;
            }

            if ( ! empty( $resources ) ) {
                $link = $this->context->link->getModuleLink( $this->name, 'generateUrl',
                    [ 'module_name' => $this->name, 'cart_id' => $cart->id ], true );
                Media::addJsDef( array(
                    'tco_verify_url' => $link
                ) );
                $this->context->smarty->assign( 'resources', $resources );
            }

            $returnContent .= $this->context->smarty->fetch( 'module:' . $this->name . '/views/templates/front/prefetch.tpl' );
        }

        return $returnContent;
    }

    public function hookDisplayOrderConfirmation( $params ) {
        if ( ( ! isset( $params['order'] ) || $params['order']->module != $this->name ) || ! $this->active ) {
            return false;
        }

        $order = $params['order'] ?? null;
        $cart  = $params['cart'] ?? null;
        $this->smarty->assign( [ 'order' => $order, 'cart' => $cart ] );

        return $this->fetch( 'module:twocheckout/views/templates/hook/payment_return.tpl' );
    }

    /**
     * @param $params
     *
     * @return PaymentOption[]|void|void[]
     */
    public function hookPaymentOptions( $params ) {
        if ( ! $this->active || ! $this->checkCurrency( $params['cart'] ) ) {
            return;
        }
        // we clear the cache for every change we make
        Tools::clearSmartyCache();
        Tools::clearXMLCache();
        Media::clearCache();
        Tools::generateIndex();

        if ( Configuration::get( 'TWOCHECKOUT_TYPE' ) == 2 ) { // api with 2payJs
            return [ $this->getApiPaymentOption( $params['cart'] ) ];
        } elseif ( Configuration::get( 'TWOCHECKOUT_TYPE' ) == 1 ) { // inline
            return [ $this->getInlinePaymentOption() ];
        } else { // Convert+
            return [ $this->getConvertPaymentOption() ];
        }
    }

    /**
     * @param $orderReturn
     */
    public function hookActionProductCancel( $params ) {
        $apiResponse = [];
        $order       = isset( $params['order'] ) ? $params['order'] : null;
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {
            if ( $order->getCurrentOrderState()->id != Configuration::get( 'PS_OS_REFUND' ) ) {
                $orderPayment = OrderPayment::getByOrderReference( $order->reference );
                $Refno        = null;
                foreach ( $orderPayment as $payment ) {
                    $invoice = $payment->getOrderInvoice( $order->id );
                    if ( $invoice ) {
                        $Refno = trim( $payment->transaction_id );
                    }
                }

                //Prepare comment and get only the 150 accepted characters.
                $refundCommentStr = Tools::getValue( 'tco-refund-comment', '' );
                $refundComment    = trim( substr( $refundCommentStr, 0, 150 ) );
                $refundReason     = self::REFUND_REASON;

                if ( ! empty( $Refno ) ) {
                    $orderData = $this->tcoApi->call( "orders/" . $Refno . "/", [], 'GET' );
                    if ( $order->total_paid == $orderData["GrossPrice"] ) {
                        // Refund Details
                        $refundDetails = [
                            "amount"  => $order->total_paid,
                            "comment" => $refundComment,
                            "reason"  => $refundReason
                        ];
                    } else {
                        $lineItems = $orderData["Items"];
                        usort( $lineItems, "cmpPrices" );
                        $lineitemReference = $lineItems[0]["LineItemReference"];
                        if ( $lineItems[0]['Price']['GrossPrice'] >= $params['amount'] ) {
                            // Refund Item Details
                            $itemsArray[] = [
                                "Quantity"          => "1",
                                "LineItemReference" => $lineitemReference,
                                "Amount"            => $order->total_paid
                            ];

                            // Refund Details
                            $refundDetails = [
                                "amount"  => $order->total_paid,
                                "comment" => $refundComment,
                                "reason"  => $refundReason,
                                "items"   => $itemsArray
                            ];
                        } else {
                            return [
                                'status'  => 'error',
                                'rawdata' => 'Partial refund amount cannot exceed the highest priced item. Please login to your 2Checkout admin to issue the partial refund manually.',
                                'transid' => $Refno,
                            ];
                        }
                    }

                    if ( ! empty( $Refno ) ) {
                        $apiResponse = $this->tcoApi->call( 'orders/' . $Refno . '/refund/', $refundDetails, 'POST' );
                    }
                }

                if ( isset( $apiResponse['error_code'] ) ) {
                    error_log( sprintf(
                        'Error Refunding Invoice with error code: "%s"',
                        isset( $apiResponse['error_code'] ) ? $apiResponse['error_code'] : 'An unknown error occurred'
                    ), 0 );

                    $error_msg = $this->l( 'Error Refunding Invoice for order "' . $order->reference . '" with transaction id "'
                                           . $Refno . '". Message: ' . $apiResponse['message'] . ' ' );

                    $this->context->controller->errors['2co_refund_error'] = $error_msg;
                } else {
                    $order->setCurrentState( Configuration::get( 'PS_OS_REFUND' ) );
                }
            }
        }
    }

    public function hookDisplayAdminOrderTop( $params ) {
        $id_order = isset( $params['id_order'] ) ? $params['id_order'] : null;
        $order    = new Order( (int) $id_order );
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {
            $errors = $this->getAdminOrderPage2CoRefundErrors( $params );

            if ( ! empty( $errors ) ) {
                $this->context->controller->errors[] = $errors;
            }

            $return = $this->disablePartialRefund();
            $return .= $this->getRefundCommentBox();
            $return .= $this->getTotalItemsForRefund( $order );

            return $return;
        }
    }

    public function hookDisplayAdminOrder( $params ) {
        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return false;
        }
        $id_order = isset( $params['id_order'] ) ? $params['id_order'] : null;
        $order    = new Order( (int) $id_order );
        if ( Validate::isLoadedObject( $order ) && $order->module === $this->name ) {

            $errors = $this->getAdminOrderPage2CoRefundErrors( $params );

            if ( ! empty( $errors ) ) {
                $this->context->controller->errors[] = $errors;
            }
            $return = $this->disablePartialRefund();
            $return .= $this->getRefundCommentBox();
            $return .= $this->getTotalItemsForRefund( $order );

            return $return;
        }
    }

    private function getRefundCommentBox() {
        $this->context->smarty->assign(
            [
                'tco_refund_comment_box'    => $this->trans( 'Refund Comment...' ),
                'tco_refund_max_length_str' => $this->trans( '*Max 150 characters.' ),
                'tco_refund_max_length'     => 150
            ] );

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundCommentBox17x.tpl' );

        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundCommentBox.tpl' );
    }

    private function getTotalItemsForRefund( $order ) {
        $products    = $order->getProducts();
        $prods_array = [];
        foreach ( $products as $prod_id => $params ) {
            $prods_array[ $prod_id ] = $params['product_quantity'];
        }
        $notAllProductsAlert = $this->getTranslator()->trans( 'Please select all products!' );
        $hasPaidShipping     = $this->hasPaidShipping( $order->getShipping() );
        $shippingMsgAlert    = $this->getTranslator()->trans( 'Order does not have free shipping. Please include that in full refund!' );
        $this->context->smarty->assign(
            [
                'tco_refund_products_list' => json_encode( $prods_array ),
                'not_all_products_alert'   => $notAllProductsAlert,
                'has_paid_shipping'        => $hasPaidShipping,
                'shipping_msg_alert'       => $shippingMsgAlert
            ] );

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundItemsCorrection17x.tpl' );
        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/refundItemsCorrection.tpl' );
    }

    private function getAdminOrderPage2CoRefundErrors( $params ) {
        $twocheckout_msg = '';
        if ( isset( $this->context->controller->errors['2co_refund_error'] ) ) {
            $twocheckout_msg = $this->context->controller->errors['2co_refund_error'];
        }

        return $twocheckout_msg;
    }

    private function disablePartialRefund() {

        if ( version_compare( _PS_VERSION_, '1.7.7', '>=' ) ) {
            return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/disablePartialRefund17x.tpl' );
        }

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/disablePartialRefund.tpl' );
    }

    /**
     * @param $cart
     *
     * @return bool
     */
    public function checkCurrency( $cart ) {
        $currency_order    = new Currency( $cart->id_currency );
        $currencies_module = $this->getCurrency( $cart->id_currency );

        if ( is_array( $currencies_module ) ) {
            foreach ( $currencies_module as $currency_module ) {
                if ( $currency_order->id == $currency_module['id_currency'] ) {
                    return true;
                }
            }
        }

        return false;
    }


    /**
     * @return PaymentOption|void
     */
    public function getInlinePaymentOption() {
        if ( ! $this->active ) {
            return;
        }
        $newOption = new PaymentOption();
        $newOption->setCallToActionText( 'Pay with 2Checkout' )
                  ->setAction( 'javascript:TwocheckoutInlineCheckout()' );

        return $newOption;
    }

    /**
     * @return PaymentOption|void
     */
    public function getConvertPaymentOption() {
        if ( ! $this->active ) {
            return;
        }
        $newOption = new PaymentOption();
        $newOption->setCallToActionText( 'Pay with 2Checkout' )
                  ->setAction( 'javascript:TwocheckoutCPCheckout()' );

        return $newOption;
    }

    /**
     * 2payJS->API payment method
     * @return PaymentOption
     * @throws SmartyException
     */
    public function getApiPaymentOption( $cart ) {
        if ( ! $this->active ) {
            return;
        }
        $newApiOption = new PaymentOption();
        $newApiOption->setCallToActionText($this->l('Pay with 2Checkout'))
                     ->setAction('javascript:Twocheckout2PayJs()')
                     ->setBinary(true)
                     ->setForm($this->generateApiForm($cart));

        return $newApiOption;
    }

    /**
     * genereates the form for the payment option (2payJs)
     * @return string
     * @throws SmartyException
     */
    protected function generateApiForm( $cart ) {

        // get style and remove newlines
        if ( Configuration::get( 'TWOCHECKOUT_STYLE_DEFAULT_MODE' ) ) {
            $style = trim( preg_replace( '/\s\s+/', ' ', $this->getDefaultStyle() ) );
        } else {
            $style = trim( preg_replace( '/\s\s+/', ' ', Configuration::get( 'TWOCHECKOUT_STYLE' ) ) );
        }
        $this->context->smarty->assign( [
            'action'   => $this->context->link->getModuleLink( $this->name, 'generateUrl',
                [ 'module_name' => $this->name, 'cart_id' => $cart->id ], true ),
            'sellerId' => Configuration::get( 'TWOCHECKOUT_SID' ),
            'style'    => $style,
            'script'   => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/js/twocheckout.js' ),
            'css'      => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/css/twocheckout.css' ),
            'spinner'  => Media::getMediaPath( _PS_MODULE_DIR_ . $this->name . '/views/assets/images/spinner.gif' ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/front/payment_form.tpl' );
    }

    /**
     * generates the form for the payment option (convert+ & inline)
     * @return string
     * @throws SmartyException
     */
    protected function generateInlineForm() {
        $this->context->smarty->assign( [
            'action' => $this->context->link->getModuleLink( $this->name, 'validation', [], true ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/inline_payment_options.tpl' );
    }

    /**
     * generates the form for the payment option (convert+ & inline)
     * @return string
     * @throws SmartyException
     */
    protected function generateForm() {
        $this->context->smarty->assign( [
            'action' => $this->context->link->getModuleLink( $this->name, 'validation', [], true ),
        ] );

        return $this->context->smarty->fetch( 'module:twocheckout/views/templates/hook/payment_options.tpl' );
    }


    /**
     * @param      $params
     * @param      $secretWord
     * @param bool $fromResponse
     *
     * @return string
     */
    public function generateSignature(
        $params,
        $secretWord,
        $fromResponse = false
    ) {

        if ( ! $fromResponse ) {
            $signParams = array_filter( $params, function ( $k ) {
                return in_array( $k, $this->_signParams );
            }, ARRAY_FILTER_USE_KEY );
        } else {
            $signParams = $params;
            if ( isset( $signParams['signature'] ) ) {
                unset( $signParams['signature'] );
            }
        }

        ksort( $signParams ); // order by key
        // Generate Hash
        $string = '';
        foreach ( $signParams as $key => $value ) {
            $string .= strlen( $value ) . $value;
        }

        return bin2hex( hash_hmac( 'sha256', $string, $secretWord, true ) );
    }


    /**
     * @param        $delivery
     * @param string $stateCode
     * @param string $countryIsoCode
     * @param string $email
     *
     * @return array
     */
    public function getBillingDetails( $delivery, string $stateCode, string $countryIsoCode, string $email = '' ) {

        $address = [
            'Address1'    => $delivery->address1,
            'City'        => $delivery->city,
            'State'       => $stateCode,
            'CountryCode' => $countryIsoCode,
            'Email'       => $email,
            'FirstName'   => $delivery->firstname,
            'LastName'    => $delivery->lastname,
            'Phone'       => $delivery->phone,
            'Zip'         => $delivery->postcode,
            'Company'     => $delivery->company,
            'FiscalCode'  => $delivery->vat_number
        ];

        if ( $delivery->address2 ) {
            $address['Address2'] = $delivery->address2;
        }

        return $address;
    }

    /**
     * for safety reasons we only send one Item with the grand total and the Cart_id as ProductName (identifier)
     * sending products order as ONE we dont have to calculate the total fee of the order (product price, tax, discounts etc)
     *
     * @param int $cart_id
     * @param float $total
     *
     * @return array
     */
    public function getItem( int $cart_id, float $total ) {
        $items[] = [
            'Code'             => null,
            'Quantity'         => 1,
            'Name'             => 'Cart_' . $cart_id,
            'Description'      => 'N/A',
            'RecurringOptions' => null,
            'IsDynamic'        => true,
            'Tangible'         => false,
            'PurchaseType'     => 'PRODUCT',
            'Price'            => [
                'Amount' => number_format( $total, 2, '.', '' ),
                'Type'   => 'CUSTOM'
            ]
        ];

        return $items;
    }

    /**
     * @param string $token
     * @param string $currency
     * @param int $cartId
     * @param int $orderId
     *
     * @return array
     */
    public function getPaymentDetails( string $token, string $currency, int $cartId ) {
        return [
            'Type'          => Configuration::get( 'TWOCHECKOUT_DEMO' ) == 1 ? 'TEST' : 'EES_TOKEN_PAYMENT',
            'Currency'      => strtolower( $currency ),
            'CustomerIP'    => $this->getCustomerIp(),
            'PaymentMethod' => [
                'EesToken'           => $token,
                'Vendor3DSReturnURL' => $this->context->link->getModuleLink( 'twocheckout', 'redirect3ds',
                    [ 'action' => 'success', 'cart' => $cartId ], true ),
                'Vendor3DSCancelURL' => $this->context->link->getModuleLink( 'twocheckout', 'redirect3ds',
                    [ 'action' => 'cancel', 'cart' => $cartId ], true )
            ]
        ];
    }

    /**
     * @param $has3ds
     *
     * @return string|null
     */
    public function hasAuthorize3DS( $has3ds ) {
        if ( isset( $has3ds ) && isset( $has3ds['Href'] ) && ! empty( $has3ds['Href'] ) ) {

            return $has3ds['Href'] . '?avng8apitoken=' . $has3ds['Params']['avng8apitoken'];
        }

        return null;
    }

    /**
     * get customer ip or returns a default ip
     * @return mixed|string
     */
    public function getCustomerIp() {
        if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
            //ip from share internet
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            //ip pass from proxy
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) === false ) {
            return $ip;
        }

        return '1.0.0.1';
    }

    public function checkActiveModule() {
        $active  = false;
        $modules = Hook::getHookModuleExecList( 'paymentOptions' );
        if ( empty( $modules ) ) {
            return;
        }
        foreach ( $modules as $module ) {
            if ( $module['module'] == $this->name ) {
                $active = true;
            }
        }

        return $active;
    }

    public function hasPaidShipping( $shippingArr ) {
        $total = 0;
        foreach ( $shippingArr as $shipping => $valuesArr ) {
            $total += $valuesArr['shipping_cost_tax_incl'];
        }

        return $total > 0;
    }

×
×
  • Create New...