How to Create a New Payment Gateway Extension for OpenCart 3

Creating a new payment gateway extension for OpenCart 3 involves several steps. This guide will walk you through the process from start to finish, ensuring you understand each part and can develop a functional payment gateway extension.

Prerequisites

Before you start, ensure you have:

  • A local development environment set up with OpenCart 3.
  • Basic knowledge of PHP, HTML, and CSS.
  • Familiarity with the MVC (Model-View-Controller) architecture.

Step 1: Set Up Your Development Environment

  1. Install OpenCart 3:
  • Download the latest version of OpenCart 3 from the official website.
  • Follow the installation instructions to set up OpenCart on your local server.
  1. Create a New Directory for Your Extension:
  • Navigate to the upload directory of your OpenCart installation.
  • Create a new directory named extension/payment/your_payment_gateway.

Step 2: Create the Controller

The controller handles the logic for your payment gateway. Create a file named your_payment_gateway.php in catalog/controller/extension/payment/.

<?php
class ControllerExtensionPaymentYourPaymentGateway extends Controller {
    public function index() {
        $this->load->language('extension/payment/your_payment_gateway');

        $data['button_confirm'] = $this->language->get('button_confirm');
        $data['action'] = $this->url->link('extension/payment/your_payment_gateway/confirm', '', true);

        return $this->load->view('extension/payment/your_payment_gateway', $data);
    }

    public function confirm() {
        // Your payment gateway confirmation logic
    }
}

Step 3: Create the Language File

Create a language file to store text strings used in your extension. Create a file named your_payment_gateway.php in catalog/language/en-gb/extension/payment/.

<?php
// Heading
$_['heading_title'] = 'Your Payment Gateway';

// Text
$_['text_extension'] = 'Extensions';
$_['text_success'] = 'Success: You have modified Your Payment Gateway account details!';
$_['text_edit'] = 'Edit Your Payment Gateway';
$_['text_your_payment_gateway'] = '<a href="https://www.yourpaymentgateway.com" target="_blank"><img src="view/image/payment/your_payment_gateway.png" alt="Your Payment Gateway" title="Your Payment Gateway" style="border: 1px solid #EEEEEE;" /></a>';

// Entry
$_['entry_status'] = 'Status';
$_['entry_sort_order'] = 'Sort Order';
$_['entry_merchant_id'] = 'Merchant ID';
$_['entry_secret_key'] = 'Secret Key';

// Error
$_['error_permission'] = 'Warning: You do not have permission to modify payment Your Payment Gateway!';
$_['error_merchant_id'] = 'Merchant ID Required!';
$_['error_secret_key'] = 'Secret Key Required!';

Step 4: Create the View

Create the view file for your payment form. Create a file named your_payment_gateway.twig in catalog/view/theme/default/template/extension/payment/.

<form action="{{ action }}" method="post">
    <div class="buttons">
        <div class="pull-right">
            <input type="submit" value="{{ button_confirm }}" class="btn btn-primary" />
        </div>
    </div>
</form>

Step 5: Create the Admin Controller

Create a controller for the admin panel to manage your extension settings. Create a file named your_payment_gateway.php in admin/controller/extension/payment/.

<?php
class ControllerExtensionPaymentYourPaymentGateway extends Controller {
    private $error = array();

    public function index() {
        $this->load->language('extension/payment/your_payment_gateway');

        $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_your_payment_gateway', $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));
        }

        $data['heading_title'] = $this->language->get('heading_title');

        $data['text_edit'] = $this->language->get('text_edit');
        $data['text_enabled'] = $this->language->get('text_enabled');
        $data['text_disabled'] = $this->language->get('text_disabled');

        $data['entry_status'] = $this->language->get('entry_status');
        $data['entry_sort_order'] = $this->language->get('entry_sort_order');
        $data['entry_merchant_id'] = $this->language->get('entry_merchant_id');
        $data['entry_secret_key'] = $this->language->get('entry_secret_key');

        $data['button_save'] = $this->language->get('button_save');
        $data['button_cancel'] = $this->language->get('button_cancel');

        if (isset($this->error['warning'])) {
            $data['error_warning'] = $this->error['warning'];
        } else {
            $data['error_warning'] = '';
        }

        if (isset($this->error['merchant_id'])) {
            $data['error_merchant_id'] = $this->error['merchant_id'];
        } else {
            $data['error_merchant_id'] = '';
        }

        if (isset($this->error['secret_key'])) {
            $data['error_secret_key'] = $this->error['secret_key'];
        } else {
            $data['error_secret_key'] = '';
        }

        $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/your_payment_gateway', 'user_token=' . $this->session->data['user_token'], true)
        );

        $data['action'] = $this->url->link('extension/payment/your_payment_gateway', '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_your_payment_gateway_status'])) {
            $data['payment_your_payment_gateway_status'] = $this->request->post['payment_your_payment_gateway_status'];
        } else {
            $data['payment_your_payment_gateway_status'] = $this->config->get('payment_your_payment_gateway_status');
        }

        if (isset($this->request->post['payment_your_payment_gateway_sort_order'])) {
            $data['payment_your_payment_gateway_sort_order'] = $this->request->post['payment_your_payment_gateway_sort_order'];
        } else {
            $data['payment_your_payment_gateway_sort_order'] = $this->config->get('payment_your_payment_gateway_sort_order');
        }

        if (isset($this->request->post['payment_your_payment_gateway_merchant_id'])) {
            $data['payment_your_payment_gateway_merchant_id'] = $this->request->post['payment_your_payment_gateway_merchant_id'];
        } else {
            $data['payment_your_payment_gateway_merchant_id'] = $this->config->get('payment_your_payment_gateway_merchant_id');
        }

        if (isset($this->request->post['payment_your_payment_gateway_secret_key'])) {
            $data['payment_your_payment_gateway_secret_key'] = $this->request->post['payment_your_payment_gateway_secret_key'];
        } else {
            $data['payment_your_payment_gateway_secret_key'] = $this->config->get('payment_your_payment_gateway_secret_key');
        }

        $this->response->setOutput($this->load->view('extension/payment/your_payment_gateway', $data));
    }

    protected function validate() {
        if (!$this->user->hasPermission('modify', 'extension/payment/your_payment_gateway')) {
            $this->error['warning'] = $this->language->get('error_permission');
        }

        if (!$this->request->post['payment_your_payment_gateway_merchant_id']) {
            $this->error['merchant_id'] = $this->language->get('error_merchant_id');
        }

        if (!$this->request->post['payment_your_payment_gateway_secret_key']) {
            $this->error['secret_key'] = $this->language->get('error_secret_key');
        }

        return !$this->error

;
    }
}

Step 6: Create the Admin Language File

Create a language file for the admin panel. Create a file named your_payment_gateway.php in admin/language/en-gb/extension/payment/.

<?php
// Heading
$_['heading_title'] = 'Your Payment Gateway';

// Text
$_['text_extension'] = 'Extensions';
$_['text_success'] = 'Success: You have modified Your Payment Gateway account details!';
$_['text_edit'] = 'Edit Your Payment Gateway';

// Entry
$_['entry_status'] = 'Status';
$_['entry_sort_order'] = 'Sort Order';
$_['entry_merchant_id'] = 'Merchant ID';
$_['entry_secret_key'] = 'Secret Key';

// Error
$_['error_permission'] = 'Warning: You do not have permission to modify payment Your Payment Gateway!';
$_['error_merchant_id'] = 'Merchant ID Required!';
$_['error_secret_key'] = 'Secret Key Required!';

Step 7: Create the Admin View

Create a view file for the admin panel to manage the extension settings. Create a file named your_payment_gateway.twig in admin/view/template/extension/payment/.

<div class="container">
    <div class="row">
        <div class="col-md-12">
            {{ 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 required">
                                    <label class="col-sm-2 control-label" for="input-merchant-id">{{ entry_merchant_id }}</label>
                                    <div class="col-sm-10">
                                        <input type="text" name="payment_your_payment_gateway_merchant_id" value="{{ payment_your_payment_gateway_merchant_id }}" placeholder="{{ entry_merchant_id }}" id="input-merchant-id" class="form-control" />
                                        {% if error_merchant_id %}
                                            <div class="text-danger">{{ error_merchant_id }}</div>
                                        {% endif %}
                                    </div>
                                </div>
                                <div class="form-group required">
                                    <label class="col-sm-2 control-label" for="input-secret-key">{{ entry_secret_key }}</label>
                                    <div class="col-sm-10">
                                        <input type="text" name="payment_your_payment_gateway_secret_key" value="{{ payment_your_payment_gateway_secret_key }}" placeholder="{{ entry_secret_key }}" id="input-secret-key" class="form-control" />
                                        {% if error_secret_key %}
                                            <div class="text-danger">{{ error_secret_key }}</div>
                                        {% endif %}
                                    </div>
                                </div>
                                <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_your_payment_gateway_status" id="input-status" class="form-control">
                                            <option value="1" {% if payment_your_payment_gateway_status %} selected {% endif %}>{{ text_enabled }}</option>
                                            <option value="0" {% if not payment_your_payment_gateway_status %} selected {% endif %}>{{ text_disabled }}</option>
                                        </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_your_payment_gateway_sort_order" value="{{ payment_your_payment_gateway_sort_order }}" placeholder="{{ entry_sort_order }}" id="input-sort-order" class="form-control" />
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
                {{ footer }}
            </div>
        </div>
    </div>
</div>

Step 8: Add SQL for Extension Installation

When the extension is installed, you may need to add some SQL to create any necessary tables or modify existing ones. You can do this in the install and uninstall methods of your admin controller.

public function install() {
    $this->load->model('extension/payment/your_payment_gateway');
    $this->model_extension_payment_your_payment_gateway->install();
}

public function uninstall() {
    $this->load->model('extension/payment/your_payment_gateway');
    $this->model_extension_payment_your_payment_gateway->uninstall();
}

In the admin/model/extension/payment/your_payment_gateway.php file, add the following methods:

public function install() {
    // Add your installation SQL here
}

public function uninstall() {
    // Add your uninstallation SQL here
}

Step 9: Test Your Extension

  1. Install the Extension:
  • Go to Extensions > Extensions in the admin panel.
  • Select “Payments” from the dropdown.
  • Find your payment gateway and click the install button.
  1. Configure the Extension:
  • Click the edit button for your payment gateway.
  • Enter the required settings (e.g., Merchant ID, Secret Key) and save.
  1. Test the Payment Process:
  • Place an order in your OpenCart store.
  • Select your payment gateway during checkout.
  • Ensure that the payment process works as expected.
See also  State Management with Alpine.js and Laravel

Conclusion

Creating a new payment gateway extension for OpenCart 3 involves setting up controllers, views, and language files for both the catalog and admin sides. By following this guide, you should be able to create a functional payment gateway extension tailored to your needs. Remember to test thoroughly and ensure that your extension meets all security and performance requirements.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.