Reading list Switch to dark mode

    How to create a payment extension in Opencart ?

    Updated 24 April 2023

    This blog describes how a developer can create a new Payment extension in Opencart version 3.0.3.8.

    Nowadays Online payment systems play an vital role which is like a backbone in e-commerce. In simple terms, payment processing refers to accepting and handling customer payments. This process includes various steps, such as capturing payment information, authorization of the transaction, and transferring funds from the customer’s account to the merchant’s account. It builds trust between merchants and customers.

    Opencart itself offers a variety of core payment methods such as bank transfers, 2Checkout, Cash On Delivery, and some Online Payment methods. Here You can check the list of our Payment Extensions.

    Before making a payment extension, the things that you need to know

    • create an account at the payment gateway and gather all the necessary and vital information about the payment like the API documentation, API keys, and other credentials required to integrate that payment method.

    In Opencart, extensions are of various types. Because we want to create a payment extension, our extension will be of type “payment”.

    first of all, you have to make directory Structure like :

    Searching for an experienced
    Opencart Company ?
    Find out More

    For payment extension, All the files are required (except admin/model/extension/payment/first_payment.php) and should be arranged in the same hierarchical manner.

    directory

    Let’s start Building Payment File for Admin End

    1. Controller file – At the beginning of development, create a payment controller file with the name “first_payment.php” inside the folder “admin/controller/extension/payment”.
      
      <?php
      /**
      * Webkul Software.
      *
      * @category Webkul
      * @package Opencart Module Tutorial
      * @author Webkul
      * @license https://store.webkul.com/license.html
      */
    class ControllerExtensionPaymentFirstPayment extends Controller {
    	private $error = array();
    
    	public function index() {
    		$this->load->language('extension/payment/first_payment');
            
    		//heading title
    		$this->document->setTitle($this->language->get('heading_title'));
    
    		$this->load->model('setting/setting');
    	
    		if(($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { 
    			$this->model_setting_setting->editSetting('payment_first_payment', $this->request->post);
    
    			$this->session->data['success'] = $this->language->get('text_success');
    
    			$this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true));
    		}
    
    		if (isset($this->error['warning'])) {
    			$data['error_warning'] = $this->error['warning'];
    		} else {
    			$data['error_warning'] = '';
    		}
    
            // breadcrumbs
    		$data['breadcrumbs'] = array();
    
    		$data['breadcrumbs'][] = array(
    			'text' => $this->language->get('text_home'),
    			'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true)
    		);
    
    		$data['breadcrumbs'][] = array(
    			'text' => $this->language->get('text_extension'),
    			'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true)
    		);
    
    		$data['breadcrumbs'][] = array(
    			'text' => $this->language->get('heading_title'),
    			'href' => $this->url->link('extension/payment/first_payment', 'user_token=' . $this->session->data['user_token'], true)
    		);
    
            // payment action mode
    		$data['action'] = $this->url->link('extension/payment/first_payment', 'user_token=' . $this->session->data['user_token'], true);
    
    		$data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true);
    
    		if (isset($this->request->post['payment_first_payment_status'])) {
    			$data['payment_first_payment_status'] = $this->request->post['payment_first_payment_status'];
    		} else {
    			$data['payment_first_payment_status'] = $this->config->get('payment_first_payment_status');
    		}
    
    		$this->load->model('localisation/order_status');
    
    		$data['order_statuses'] = $this->model_localisation_order_status->getOrderStatuses();
    
    		if (isset($this->request->post['payment_first_payment_order_status_id'])) {
    			$data['payment_first_payment_order_status_id'] = $this->request->post['payment_first_payment_order_status_id'];
    		} else {
    			$data['payment_first_payment_order_status_id'] = $this->config->get('payment_first_payment_order_status_id');
    		}
    
    		$this->load->model('localisation/geo_zone');
    
    		$data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
    
    		if (isset($this->request->post['payment_first_payment_geo_zone_id'])) {
    			$data['payment_first_payment_geo_zone_id'] = $this->request->post['payment_first_payment_geo_zone_id'];
    		} else {
    			$data['payment_first_payment_geo_zone_id'] = $this->config->get('payment_first_payment_geo_zone_id');
    		}
    
    		if (isset($this->request->post['payment_first_payment_sort_order'])) {
    			$data['payment_first_payment_sort_order'] = $this->request->post['payment_first_payment_sort_order'];
    		} else {
    			$data['payment_first_payment_sort_order'] = $this->config->get('payment_first_payment_sort_order');
    		}
    
    		$data['header'] = $this->load->controller('common/header');
    		$data['column_left'] = $this->load->controller('common/column_left');
    		$data['footer'] = $this->load->controller('common/footer');
    
    		$this->response->setOutput($this->load->view('extension/payment/first_payment', $data));
    	}
    
    	protected function validate() {
    		if (!$this->user->hasPermission('modify', 'extension/payment/first_payment')) {
    			$this->error['warning'] = $this->language->get('error_permission');
    		}
    		return !$this->error;
    	}
     }

    2. Language file – We’ll need more entries inside our language to display input form errors and placeholders and labels and buttons. So just overwrite “admin/language/en-gb/extension/payment/first_payment.php” with this.

     
    <?php
      /**
      * Webkul Software.
      *
      * @category Webkul
      * @package Opencart Module Tutorial
      * @author Webkul
      * @license https://store.webkul.com/license.html
      */
    // Heading
    $_['heading_title']      = 'First Payment';
    
    // Text
    $_['text_extension']     = 'Extensions';
    $_['text_success']       = 'Success: You have modified First Payment details!';
    $_['text_edit']          = 'Edit First Payment';
    
    // Entry
    $_['entry_order_status'] = 'Order Status';
    $_['entry_geo_zone']     = 'Geo Zone';
    $_['entry_status']       = 'Status';
    $_['entry_sort_order']   = 'Sort Order';
    
    // Help
    $_['help_total']         = 'The checkout total the order must reach before this payment method becomes active.'; 
    
    // Error 
    $_['error_permission']   = 'Warning: You do not have permission to modify First Payment!';

    3. View file – Create layout at admin end using twig file “admin/view/template/extension/first_payment.twig”, consider all the required fields for the payment method configuration.

    <!-- 
    /**
     * Webkul Software.
     *
     * @category Webkul
     * @package Opencart Module Tutorial
     * @author Webkul
     * @license https://store.webkul.com/license.html
     */
     -->
    
     {{ header }}{{ column_left }}
    <div id="content">
      <div class="page-header">
        <div class="container-fluid">
          <div class="pull-right">
            <button type="submit" form="form-payment" data-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary"><i class="fa fa-save"></i></button>
            <a href="{{ cancel }}" data-toggle="tooltip" title="{{ button_cancel }}" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
          <h1>{{ heading_title }}</h1>
          <ul class="breadcrumb">
            {% for breadcrumb in breadcrumbs %}
            <li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
            {% endfor %}
          </ul>
        </div>
      </div>
      <div class="container-fluid">
        {% if error_warning %}
        <div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ error_warning }}
          <button type="button" class="close" data-dismiss="alert">&times;</button>
        </div>
        {% endif %}
        <div class="panel panel-default">
          <div class="panel-heading">
            <h3 class="panel-title"><i class="fa fa-pencil"></i> {{ text_edit }}</h3>
          </div>
          <div class="panel-body">
            <form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-payment" class="form-horizontal">
               <div class="form-group">
                <label class="col-sm-2 control-label" for="input-status">{{ entry_status }}</label>
                <div class="col-sm-10">
                  <select name="payment_first_payment_status" id="input-status" class="form-control">
                    {% if payment_first_payment_status %}
                    <option value="1" selected="selected">{{ text_enabled }}</option>
                    <option value="0">{{ text_disabled }}</option>
                    {% else %}
                    <option value="1">{{ text_enabled }}</option>
                    <option value="0" selected="selected">{{ text_disabled }}</option>
                    {% endif %}
                  </select>
                </div>
              </div>
              <div class="form-group">
                <label class="col-sm-2 control-label" for="input-order-status">{{ entry_order_status }}</label>
                <div class="col-sm-10">
                  <select name="payment_first_payment_order_status_id" id="input-order-status" class="form-control">
                    {% for order_status in order_statuses %}
                    {% if order_status.order_status_id == payment_first_payment_order_status_id %}
                    <option value="{{ order_status.order_status_id }}" selected="selected">{{ order_status.name }}</option>
                    {% else %}
                    <option value="{{ order_status.order_status_id }}">{{ order_status.name }}</option>
                    {% endif %}
                    {% endfor %}
                  </select>
                </div>
              </div>
              <div class="form-group">
                <label class="col-sm-2 control-label" for="input-geo-zone">{{ entry_geo_zone }}</label>
                <div class="col-sm-10">
                  <select name="payment_first_payment_geo_zone_id" id="input-geo-zone" class="form-control">
                    <option value="0">{{ text_all_zones }}</option>
                    {% for geo_zone in geo_zones %}
                    {% if geo_zone.geo_zone_id == payment_first_payment_geo_zone_id %}
                    <option value="{{ geo_zone.geo_zone_id }}" selected="selected">{{ geo_zone.name }}</option>
                    {% else %}
                    <option value="{{ geo_zone.geo_zone_id }}">{{ geo_zone.name }}</option>
                    {% endif %}
                    {% endfor %}
                  </select>
                </div>
              </div>     
              <div class="form-group">
                <label class="col-sm-2 control-label" for="input-sort-order">{{ entry_sort_order }}</label>
                <div class="col-sm-10">
                  <input type="text" name="payment_first_payment_sort_order" value="{{ payment_first_payment_sort_order }}" placeholder="{{ entry_sort_order }}" id="input-sort-order" class="form-control" />
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
    {{ footer }}

    So, we have completed building our first payment module. now, we will install this by heading to Extensions-> Extensions-> Payment -> First payment from the admin panel, and after installing you can configure the payment module by enabling it.

    installation
    view

    Let’s start Building Payment File for Front End

    1. Controller File – All the necessary methods (including index) will be kept in the controller file “catalog/controller/extension/payment/first_payment.php”.
     <?php
      /**
      * Webkul Software.
      *
      * @category Webkul
      * @package Opencart Module Tutorial
      * @author Webkul
      * @license https://store.webkul.com/license.html
      */
     
      class ControllerExtensionPaymentFirstPayment extends Controller {
    	public function index() {
    		$data = array();
    		$this->load->language('extension/payment/first_payment');
    
           	return $this->load->view('extension/payment/first_payment', $data);
    	}
    
    	public function send() {
    		    $json = array();
    	        if(isset($this->session->data['payment_method']['code']) && $this->session->data['payment_method']['code'] == 'first_payment') {
    			$this->load->language('extension/payment/first_payment');
    	
    			$this->load->model('checkout/order');
    	
    			$this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('payment_first_payment_order_status_id'),'', true);
    			
    			$json['redirect'] = $this->url->link('checkout/success');
    			}
    			
    			$this->response->addHeader('Content-Type: application/json');
    			$this->response->setOutput(json_encode($json));		
    	    }
    		
    	}

    2. Language File – For add text, inputs, placeholders for front end, will include same as admin-end at path “catalog/language/en-gb/extension/payment/first_payment.php”.

    <?php
     /**
      * Webkul Software.
      *
      * @category Webkul
      * @package Opencart Module Tutorial
      * @author Webkul
      * @license https://store.webkul.com/license.html
      */
    // Text
    $_['text_title']         = 'First Payment';
    $_['text_desciption']    = 'Please transfer the total amount to the following bank account 9746737733';
    $_['text_notice']        = 'Your order will not ship until we receive payment.';

    3. Model file – All the data operations for the payment method can be managed by using the model file “catalog/model/extension/payment/first_payment.php” .

     <?php
     /**
      * Webkul Software.
      *
      * @category Webkul
      * @package Opencart Module Tutorial
      * @author Webkul
      * @license https://store.webkul.com/license.html
      */
     class ModelExtensionPaymentFirstPayment extends Model {
    	public function getMethod($address, $total) {
    		$this->load->language('extension/payment/first_payment');
    
    		$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('payment_first_payment_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");
    
    		if ($this->config->get('payment_first_payment_total') > 0 && $this->config->get('payment_first_payment_total') > $total) {
    			$status = false;
    		} elseif (!$this->config->get('payment_first_payment_geo_zone_id')) {
    			$status = true;
    		} elseif ($query->num_rows) {
    			$status = true;
    		} else {
    			$status = false;
    		}
    
    		$method_data = array();
    
    		if ($status) {
    			$method_data = array(
    				'code'       => 'first_payment',
    				'title'      => $this->language->get('text_title'),
    				'terms'      => '',
    				'sort_order' => $this->config->get('payment_first_payment_sort_order')
    			);
    		}
    
    		return $method_data;
    	}
    }

    4. View File – Create web end layout for the payment method using catalog/view/theme/(theme_name or default)/template/extension/payment/first_payment.twig. We can use it while placing an order.

     <!-- 
     /**
     * Webkul Software.
     *
     * @category Webkul
     * @package Opencart Module Tutorial
     * @author Webkul
     * @license https://store.webkul.com/license.html
     */
     -->
     <h2>{{ text_title }}</h2>
    <div class="well well-sm">
      <p>{{ text_desciption }}</p>
      <p>{{ text_notice }}</p>
    </div>
    
    <div class="buttons">
      <div class="pull-right">
        <input type="button" value="{{ button_confirm }}" id="button-confirm" data-loading-text="{{ text_loading }}" class="btn btn-primary" />
      </div>
    </div>
    <script type="text/javascript"><!--
    $('#button-confirm').on('click', function() {
    	$.ajax({
    		url: 'index.php?route=extension/payment/first_payment/send',
    		dataType: 'json',
    		beforeSend: function() {
    			$('#button-confirm').button('loading');
    		},
    		complete: function() {
    			$('#button-confirm').button('reset');
    		},
    		success: function(json) {
    			if (json['redirect']) {
    				location = json['redirect'];	
    			}
    		},
    		error: function(xhr, ajaxOptions, thrownError) {
    			alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
    		}
    	});
    });
    //--></script>

    Front End For Buyers At The Checkout Page

    payment
    checkout-payment

    To do modification in the Opencart root files, you can create XML file inside install.xml and make its zip with the xyz_payment.ocmod.xml extension. We can found the above XML file within the ocmod folder of the Payment extension root directory.

    Thank You !

    If you need custom Opencart Development services then feel free to reach us and also explore our exclusive range of Opencart Extensions.

    !! Have a Great Day Ahead !!

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home