Creating Payment Module

From osCommerce Wiki
Jump to navigation Jump to search

1. File creation


First you need to create the file for the new module and place it in the following directory.

/lib/common/modules/orderPayment/

For example, let us call this new payment module custom_pay.php

The file skeleton should look in the following way:

<?php

/**
 * namespace
 */
namespace common\modules\orderPayment;

/**
 * used classes
 */
use common\classes\modules\ModulePayment;
use common\classes\modules\ModuleStatus;
use common\classes\modules\ModuleSortOrder;

/**
 * class declaration
 */
class custom_pay extends ModulePayment {

    /**
     * variables
     */
    var $code, $title, $description, $enabled;

    /**
     * default values for translation
     */
    protected $defaultTranslationArray = [
        'MODULE_PAYMENT_CUSTOM_PAY_TEXT_TITLE' => 'Custom payment',
        'MODULE_PAYMENT_CUSTOM_PAY_TEXT_DESCRIPTION' => 'Pay by credit balance',
        'MODULE_PAYMENT_CUSTOM_PAY_ERROR' => 'There has been an error processing your credit card',
    ];

    /**
     * class constructor
     */
    function __construct() {
        parent::__construct();

        $this->code = 'custom_pay';
        $this->title = MODULE_PAYMENT_CUSTOM_PAY_TEXT_TITLE;
        $this->description = MODULE_PAYMENT_CUSTOM_PAY_TEXT_DESCRIPTION;
        if (!defined('MODULE_PAYMENT_CUSTOM_PAY_STATUS')) {
            $this->enabled = false;
            return false;
        }
        $this->sort_order = MODULE_PAYMENT_CUSTOM_PAY_SORT_ORDER;
        $this->enabled = ((MODULE_PAYMENT_CUSTOM_PAY_STATUS == 'True') ? true : false);
        $this->online = false;

        if ((int) MODULE_PAYMENT_CUSTOM_PAY_ORDER_STATUS_ID > 0) {
            $this->order_status = MODULE_PAYMENT_CUSTOM_PAY_ORDER_STATUS_ID;
        }

        $this->update_status();
    }

    function update_status() {

        if (($this->enabled == true) && ((int) MODULE_PAYMENT_CUSTOM_PAY_ZONE > 0)) {
            $check_flag = false;
            $check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_CUSTOM_PAY_ZONE . "' and zone_country_id = '" . $this->delivery['country']['id'] . "' order by zone_id");
            while ($check = tep_db_fetch_array($check_query)) {
                if ($check['zone_id'] < 1) {
                    $check_flag = true;
                    break;
                } elseif ($check['zone_id'] == $this->delivery['zone_id']) {
                    $check_flag = true;
                    break;
                }
            }

            if ($check_flag == false) {
                $this->enabled = false;
            }
        }
    }

    function selection() {
        return array('id' => $this->code,
            'module' => $this->title);
    }

    function process_button() {
        return false;
    }

    function before_process() {
        try {
            $transaction_currency = \Yii::$app->settings->get('currency');
            $order = $this->manager->getOrderInstance();

            //-----------------------------------------
            // make your request here with credentials:
            // MODULE_PAYMENT_CUSTOM_PAY_USERNAME
            // MODULE_PAYMENT_CUSTOM_PAY_PASSWORD
            $result = [
                'success' => true,
                'transaction' => '',
            ];
            //-----------------------------------------
            
            if (isset($result['success']) && $result['success']) {
                $orderPayment = new \common\models\OrdersPayment();
                $orderPayment->orders_payment_module = $this->code;
                $orderPayment->orders_payment_transaction_id = $result['transaction'];
                $orderPayment->orders_payment_id_parent = 0;
                $orderPayment->orders_payment_order_id = 0;
                $orderPayment->orders_payment_is_credit = 0;
                $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_PROCESSING;
                $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $transaction_currency);
                $orderPayment->orders_payment_currency = trim($order->info['currency']);
                $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value'];
                $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order));
                $orderPayment->orders_payment_transaction_status = '';
                $orderPayment->orders_payment_transaction_commentary = '';
                $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s');
                $orderPayment->orders_payment_transaction_full = json_encode($result);
                $orderPayment->save(false);
                return true; // success
            }
            if (isset($result['data']['message'])) {
                tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($result['data']['message']), 'SSL'));
            }
        } catch (\Exception $e) {
            tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($e->getMessage()), 'SSL'));
        }
        tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(MODULE_PAYMENT_CUSTOM_PAY_ERROR), 'SSL'));
    }

    function after_process() {
        
    }

    function formatCurrencyRaw($total, $currency_code = null, $currency_value = null) {

        if (!isset($currency_code)) {
            $currency_code = DEFAULT_CURRENCY;
        }

        if (!isset($currency_value) || !is_numeric($currency_value)) {
            $currencies = \Yii::$container->get('currencies');
            $currency_value = $currencies->currencies[$currency_code]['value'];
        }

        return number_format(self::round($total * $currency_value, $currencies->currencies[$currency_code]['decimal_places']), $currencies->currencies[$currency_code]['decimal_places'], '.', '');
    }

    function isOnline() {
        return true;
    }

    public function configure_keys() {
        return array(
            'MODULE_PAYMENT_CUSTOM_PAY_STATUS' => array(
                'title' => 'Enable Custom payment Module',
                'value' => 'True',
                'description' => 'Do you want to accept Custom payments?',
                'sort_order' => '1',
                'set_function' => 'tep_cfg_select_option(array(\'True\', \'False\'), ',
            ),
            'MODULE_PAYMENT_CUSTOM_PAY_USERNAME' => array(
                'title' => 'API username',
                'value' => '',
                'description' => 'Authorization username.',
                'sort_order' => '2',
            ),
            'MODULE_PAYMENT_CUSTOM_PAY_PASSWORD' => array(
                'title' => 'API password',
                'value' => '',
                'description' => 'Authorization password.',
                'sort_order' => '3',
            ),
            'MODULE_PAYMENT_CUSTOM_PAY_ZONE' => array(
                'title' => 'Payment Zone',
                'value' => '0',
                'description' => 'If a zone is selected, only enable this payment method for that zone.',
                'sort_order' => '4',
                'use_function' => '\\common\\helpers\\Zones::get_zone_class_title',
                'set_function' => 'tep_cfg_pull_down_zone_classes(',
            ),
            'MODULE_PAYMENT_CUSTOM_PAY_ORDER_STATUS_ID' => array(
                'title' => 'Set Order Status',
                'value' => '0',
                'description' => 'Set the status of orders made with this payment module to this value',
                'sort_order' => '5',
                'set_function' => 'tep_cfg_pull_down_order_statuses(',
                'use_function' => '\\common\\helpers\\Order::get_order_status_name',
            ),
            'MODULE_PAYMENT_CUSTOM_PAY_SORT_ORDER' => array(
                'title' => 'Sort order of  display.',
                'value' => '0',
                'description' => 'Sort order of Custom payment display. Lowest is displayed first.',
                'sort_order' => '6',
            ),
        );
    }

    public function describe_status_key() {
        return new ModuleStatus('MODULE_PAYMENT_CUSTOM_PAY_STATUS', 'True', 'False');
    }

    public function describe_sort_key() {
        return new ModuleSortOrder('MODULE_PAYMENT_CUSTOM_PAY_SORT_ORDER');
    }

}

Note: Pay attention to the mandatory elements:

  • namespace indicating the class placement
  • use modules classes used for the installation creation
  • class declaration with the mandatory inheritance from ModulePayment
  • variables required for your module
  • keys for translation
  • constructor doing initialization
  • before_process function for actions
  • tax_class support
  • the minimum set of configuration fields
  • describe_status_key function responsible for the condition
  • describe_sort_key function responsible for the sort order

It is not recommended to close php tag to avoid showing the non-printable symbols on the pages.


2. Module installation


After you accessed the admin area of your website click on Modules, Payment, Online and the required frontend tabs. Switch on Show inactive and Show not installed switches, find your module and click on Install button.

Image 825.png


Check the keys and if the module is switched on. Choose the required payment zone and order status. If you have the section Available for in your version fill it in and save the changes.

Image 826.png