In this blog, we will provide a comprehensive guide on creating a payment extension in Opencart version 4. Online payment systems have become indispensable in e-commerce, acting as the backbone of transactions.
To begin, it is essential to familiarize ourselves with the folder structure of an extension.
Folder structure
Payment extension backend code
Finally, we have our folder structure in place, let’s start creating an extension, we will show ”Webkul Payment” on the checkout page.
admin/controller/payment/example_payment.php
<?php /** * Extension name: Webkul Payment * Descrption: Using this extension we will show payment methods on the checkout page. * Author: Webkul Software Pvt. Ltd. * */ namespace Opencart\Admin\Controller\Extension\ExamplePayment\Payment; class ExamplePayment extends \Opencart\System\Engine\Controller { /** * index * * @return void */ public function index(): void { $this->load->language('extension/example_payment/payment/example_payment'); $this->document->setTitle($this->language->get('heading_title')); $data['breadcrumbs'] = []; $data['breadcrumbs'][] = [ 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token']) ]; $data['breadcrumbs'][] = [ 'text' => $this->language->get('text_extension'), 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment') ]; if (!isset($this->request->get['module_id'])) { $data['breadcrumbs'][] = [ 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('extension/example_payment/payment/example_payment', 'user_token=' . $this->session->data['user_token']) ]; } else { $data['breadcrumbs'][] = [ 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('extension/example_payment/payment/example_payment', 'user_token=' . $this->session->data['user_token'] . '&module_id=' . $this->request->get['module_id']) ]; } $data['save'] = $this->url->link('extension/example_payment/payment/example_payment.save', 'user_token=' . $this->session->data['user_token']); $data['back'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment'); // getting payment extension config $data['payment_example_payment_order_status_id'] = $this->config->get('payment_example_payment_order_status_id'); // loading order status model $this->load->model('localisation/order_status'); // getting order status as array $data['order_statuses'] = $this->model_localisation_order_status->getOrderStatuses(); // zeo zone id $data['payment_example_payment_geo_zone_id'] = $this->config->get('payment_example_payment_geo_zone_id'); // loading geo_zone model $this->load->model('localisation/geo_zone'); // getting all zeo zones $data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones(); $data['payment_example_payment_status'] = $this->config->get('payment_example_payment_status'); $data['payment_example_payment_sort_order'] = $this->config->get('payment_example_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/example_payment/payment/example_payment', $data)); } /** * save method * * @return void */ public function save(): void { // loading example payment language $this->load->language('extension/example_payment/payment/example_payment'); $json = []; // checking file modification permission if (!$this->user->hasPermission('modify', 'extension/example_payment/payment/example_payment')) { $json['error']['warning'] = $this->language->get('error_permission'); } if (!$json) { $this->load->model('setting/setting'); $this->model_setting_setting->editSetting('payment_example_payment', $this->request->post); $json['success'] = $this->language->get('text_success'); } $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } }
admin/language/en-gb/payment/example_payment.php
<?php /** * Webkul Software * * @category Webkul * @package Opencart Payment Tutorial * @author [Webkul] <[<http://webkul.com/>]> * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ // Heading $_['heading_title'] = 'Webkul Payment'; // Text $_['text_extension'] = 'Extensions'; $_['text_success'] = 'Success: You have modified Webkul Payment payment module!'; $_['text_edit'] = 'Edit Webkul Payment'; // Entry $_['entry_order_status'] = 'Order Status'; $_['entry_geo_zone'] = 'Geo Zone'; $_['entry_status'] = 'Status'; $_['entry_sort_order'] = 'Sort Order'; // Error $_['error_permission'] = 'Warning: You do not have permission to modify payment Webkul Payment!';
admin/view/template/payment/example_payment.twig
{{ header }}{{ column_left }} <div id="content"> <div class="page-header"> <div class="container-fluid"> <div class="float-end"> <button type="submit" form="form-payment" data-bs-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary"><i class="fa-solid fa-save"></i></button> <a href="{{ back }}" data-bs-toggle="tooltip" title="{{ button_back }}" class="btn btn-light"><i class="fa-solid fa-reply"></i></a></div> <h1>{{ heading_title }}</h1> <ol class="breadcrumb"> {% for breadcrumb in breadcrumbs %} <li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li> {% endfor %} </ol> </div> </div> <div class="container-fluid"> <div class="card"> <div class="card-header"><i class="fa-solid fa-pencil"></i> {{ text_edit }}</div> <div class="card-body"> <form id="form-payment" action="{{ save }}" method="post" data-oc-toggle="ajax"> <div class="row mb-3"> <label for="input-order-status" class="col-sm-2 col-form-label">{{ entry_order_status }}</label> <div class="col-sm-10"> <select name="payment_example_payment_order_status_id" id="input-order-status" class="form-select"> {% for order_status in order_statuses %} <option value="{{ order_status.order_status_id }}"{% if order_status.order_status_id == payment_example_payment_order_status_id %} selected{% endif %}>{{ order_status.name }}</option> {% endfor %} </select> </div> </div> <div class="row mb-3"> <label for="input-geo-zone" class="col-sm-2 col-form-label">{{ entry_geo_zone }}</label> <div class="col-sm-10"> <select name="payment_example_payment_geo_zone_id" id="input-geo-zone" class="form-select"> <option value="0">{{ text_all_zones }}</option> {% for geo_zone in geo_zones %} <option value="{{ geo_zone.geo_zone_id }}"{% if geo_zone.geo_zone_id == payment_example_payment_geo_zone_id %} selected{% endif %}>{{ geo_zone.name }}</option> {% endfor %} </select> </div> </div> <div class="row mb-3"> <label for="input-status" class="col-sm-2 col-form-label">{{ entry_status }}</label> <div class="col-sm-10"> <div class="form-check form-switch form-switch-lg"> <input type="hidden" name="payment_example_payment_status" value="0"/> <input type="checkbox" name="payment_example_payment_status" value="1" id="input-status" class="form-check-input"{% if payment_example_payment_status %} checked{% endif %}/> </div> </div> </div> <div class="row mb-3"> <label for="input-sort-order" class="col-sm-2 col-form-label">{{ entry_sort_order }}</label> <div class="col-sm-10"> <input type="text" name="payment_example_payment_sort_order" value="{{ payment_example_payment_sort_order }}" placeholder="{{ entry_sort_order }}" id="input-sort-order" class="form-control"/> </div> </div> </form> </div> </div> </div> </div> {{ footer }}
Now, let’s initiate the development of the frontend code to display the payment methods on the checkout page.
Frontend code
catalog/controller/payment/example_payment.php
<?php /** * Extension name: Webkul Payment * Descrption: Using this extension we will show payment methods on the checkout page. * Author: Webkul Software Pvt. Ltd. * */ namespace Opencart\Catalog\Controller\Extension\ExamplePayment\Payment; class ExamplePayment extends \Opencart\System\Engine\Controller { /** * index * * @return mix */ public function index(): string { // loading example payment language $this->load->language('extension/example_payment/payment/example_payment'); $data['language'] = $this->config->get('config_language'); return $this->load->view('extension/example_payment/payment/example_payment', $data); } /** * confirm * * @return json|string */ public function confirm(): void { // loading example payment language $this->load->language('extension/example_payment/payment/example_payment'); $json = []; if (!isset($this->session->data['order_id'])) { $json['error'] = $this->language->get('error_order'); } if (!isset($this->session->data['payment_method']) || $this->session->data['payment_method']['code'] != 'example_payment.example_payment') { $json['error'] = $this->language->get('error_payment_method'); } if (!$json) { $this->load->model('checkout/order'); $this->model_checkout_order->addHistory($this->session->data['order_id'], $this->config->get('payment_example_payment_order_status_id')); $json['redirect'] = $this->url->link('checkout/success', 'language=' . $this->config->get('config_language'), true); } $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } }
catalog/model/payment/example_payment.php
<?php /** * Extension name: Webkul Payment * Descrption: Using this extension we will show payment methods on the checkout page. * Author: Webkul Software Pvt. Ltd. * */ namespace Opencart\Catalog\Model\Extension\ExamplePayment\Payment; class ExamplePayment extends \Opencart\System\Engine\Model { /** * getMethods * * @param mixed $address * @return array */ public function getMethods(array $address = []): array { // loading example payment language $this->load->language('extension/example_payment/payment/example_payment'); if ($this->cart->hasSubscription()) { $status = false; } elseif (!$this->cart->hasShipping()) { $status = false; } elseif (!$this->config->get('config_checkout_payment_address')) { $status = true; } elseif (!$this->config->get('payment_example_payment_geo_zone_id')) { $status = true; } else { // getting payment data using zeo zone $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone_to_geo_zone` WHERE `geo_zone_id` = '" . (int)$this->config->get('payment_example_payment_geo_zone_id') . "' AND `country_id` = '" . (int)$address['country_id'] . "' AND (`zone_id` = '" . (int)$address['zone_id'] . "' OR `zone_id` = '0')"); // if the rows found the status set to True if ($query->num_rows) { $status = true; } else { $status = false; } } $method_data = []; if ($status) { $option_data['example_payment'] = [ 'code' => 'example_payment.example_payment', 'name' => $this->language->get('heading_title') ]; $method_data = [ 'code' => 'example_payment', 'name' => $this->language->get('heading_title'), 'option' => $option_data, 'sort_order' => $this->config->get('payment_example_payment_sort_order') ]; } return $method_data; } }
catalog/language/en-gb/payment/example_payment.php
<?php /** * Webkul Software * * @category Webkul * @package Opencart Payment Tutorial * @author [Webkul] <[<http://webkul.com/>]> * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ // Heading $_['heading_title'] = 'Webkul Payment'; // Error $_['error_order_id'] = 'No order ID in the session!'; $_['error_payment_method'] = 'Payment method is incorrect!';
catalog/view/template/payment/example_payment.twig
<div class="text-end"> <button type="button" id="button-confirm" class="btn btn-primary">{{ button_confirm }}</button> </div> <script type="text/javascript"><!-- $('#button-confirm').on('click', function () { var element = this; $.ajax({ url: 'index.php?route=extension/example_payment/payment/example_payment.confirm&language={{ language }}', dataType: 'json', beforeSend: function () { $(element).button('loading'); }, complete: function () { $(element).button('reset'); }, success: function (json) { if (json['error']) { $('#alert').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa-solid fa-circle-exclamation"></i> ' + json['error'] + ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>'); } if (json['redirect']) { location = json['redirect']; } }, error: function (xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); }); //--></script>
Once you have created the extension, you will need to include some information within the module’s “install.json” file. This file supports the following keys: name, version, author, and link.
{ "name": "Webkul Payment Extension", "version": "1.0", "author": "Webkul Software Pvt. Ltd.", "link": "https://www.webkul.com", "instruction": "" }
Once install.json is inside the directory, you can zip it and name it that ends with .ocmod.zip, then upload it from the Opencart extension installer.
Upon successful installation of the extension, you can locate it by navigating to “Extensions > Extensions > Payment” where it will be listed for further configuration and customization.
Once the configuration is complete, the “Webkul Payment” payment method will become visible on the checkout page for you to select and proceed with your order.
These instructions will guide you through the process of creating a payment module for Opencart
If you need custom Opencart Development services then feel free to reach us and also explore our exclusive range of Opencart Addons.
2 comments