In this Opencart tutorial, we go through how to create an off-site payment extension in Opencart 3.0.3.3, in our last tutorial, we show the eCommerce payment flow that happens in Opencart, here we will show how to create the PayPal Standard payment extension, as all 3rd party extensions are removed from the download files, saying it is taking too much time to maintain but these will be uploaded to opencart.com and will be provided in a JSON string to be downloaded on demand.
SEE Difference between Off-site payment extension and On-site payment extension
Here is the step by step guide to integrate PayPal Standard in your website and here are the HTML variables than can be used on form for PayPal Standard.
For OpenCart payment extension, here are the lists of files you need to create, the link is for GitHub page where you can get all the codes, below we are just describing what is important:
- admin/controller/extension/payment/paypal_standard.php
- admin/view/image/payment/paypal.png
- admin/language/en-gb/extension/payment/paypal_standard.php
- admin/view/template/extension/payment/paypal_standard.twig
- catalog/controller/extension/payment/paypal_standard.php
- catalog/language/en-gb/extension/payment/paypal_standard.php
- catalog/model/extension/payment/paypal_standard.php
- catalog/view/theme/default/template/extension/payment/paypal_standard.twig
Here files are folders in the admin section is to create the setting fields for the payment module, for PayPal Standard seeing the HTML form:
https://developer.paypal.com/docs/paypal-payments-standard/integration-guide/formbasics/#sample-html-code-for-overriding-addresses-stored-with-paypal and https://developer.paypal.com/docs/paypal-payments-standard/ht-test-pps-buttons/#create-test-buttons-in-the-sandbox
We see the form action URL is different so that field setting is needed in the admin, merchant email or business email is need where the payment is made, transaction method whether it is an Authorization or Sale transactions, Total field, Geo Zone field, Status, Sort Order field and order status fields are needed. You can know which fields are needed by going through the documentation of the Payment method.
So, for PayPal Standard here is the output for the admin section:


Let's start with the admin controller file of Payment extension:
Open admin >> controller >> extension >> payment folder and create the paypal_standard.php, for yours you can name what your payment name is. In the file name _ is not needed, we add it just to differentiate it. Now open the paypal_standard.php and start creating the Controller Class.
As our file name is paypal_standard.php, the class name is ControllerExtensionPaymentPaypalStandard which extends the Controller base class. Although the filename includes _ (underscore), it is not needed for the Class name.
class ControllerExtensionPaymentPaypalStandard extends Controller {
Declaration of the private property ‘error’ so that we can get check if any error occurs in the whole class.
private $error = array();
Create an index method. The index method is called automatically if no parameters are passed, check this video tutorial for details https://www.youtube.com/watch?v=X6bsMmReT-4
public function index() {
Loads the language file by which the variables of language file are accessible in twig files
$this->load->language('extension/payment/paypal_standard');
Set the page or document title with following code:
$this->document->setTitle($this->language->get('heading_title'));
Loads the model admin/model/setting/setting.php so that we can use the methods defined there.
$this->load->model('setting/setting');
This is how we check if the form is submitted. When we submit the form then this block of code also runs. Then it also validates the modified permission and other validation.
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
Look at this line of codes, this is the code section which distinguishes from Single Instance to Multi-Instance. If it is a payment extension then it acts as a Single instance module, which will have editSetting function, see the first parameters "payment_paypal_standard", which need to be unique and it should start with "payment_", all $_POST values will be saved on the setting database table. Then, it sets the success message in session and then redirects to the payment listing page.
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { $this->model_setting_setting->editSetting('payment_paypal_standard', $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)); }
In the database setting table, the code is "payment_paypal_standard" and have the key which is the field name and value is the field value.

The editSetting saves the data to oc_setting database table, see payment_ is important else it will not be saved.
The following code sets the success message in the session.
$this->session->data['success'] = $this->language->get('text_success');
This code is to redirect to the payment extensions listing page.
$this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true));
This is to check if there are any warnings
if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; }
Similarly, other fields value error are checked, like for email error it is checked with the following code:
if (isset($this->error['email'])) { $data['error_email'] = $this->error['email']; } else { $data['error_email'] = ''; }
Following are for 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=module', true) ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('extension/module/login', 'user_token=' . $this->session->data['user_token'], true) );
Form action URL
$data['action'] = $this->url->link('extension/payment/paypal_standard', 'user_token=' . $this->session->data['user_token'], true);
Form cancel URL
$data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment', true);
This is to check what we fill out in the form, whether the email is added. If it is the loading time then it gets the value from the database config value which was stored in the oc_setting database table.
if (isset($this->request->post['payment_paypal_standard_email'])) { $data['payment_paypal_standard_email'] = $this->request->post['payment_paypal_standard_email']; } else { $data['payment_paypal_standard_email'] = $this->config->get('payment_paypal_standard_email'); }
Similarly, other fields are checked, like for fields payment_paypal_standard_test, payment_paypal_standard_transaction, payment_paypal_standard_debug, payment_paypal_standard_total, payment_paypal_standard_canceled_reversal_status_id, payment_paypal_standard_completed_status_id, payment_paypal_standard_denied_status_id, payment_paypal_standard_expired_status_id, payment_paypal_standard_failed_status_id, payment_paypal_standard_pending_status_id, payment_paypal_standard_processed_status_id, payment_paypal_standard_refunded_status_id, payment_paypal_standard_reversed_status_id, payment_paypal_standard_voided_status_id, payment_paypal_standard_status, and payment_paypal_standard_sort_order. You can check those all opencart codes here.
Mostly, we use geo zones for payment extensions so that we can control as per the country or zones. So to pull the geo zones in opencart we use the following code:
$this->load->model('localisation/geo_zone'); $data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
This is how we load the header, column left, and footer and pass to the template file.
$data['header'] = $this->load->controller('common/header'); $data['column_left'] = $this->load->controller('common/column_left'); $data['footer'] = $this->load->controller('common/footer');
This is to set output data variables to the view or twig files and twig file is loaded and HTML rendering is done with it.
$this->response->setOutput($this->load->view('extension/payment/paypal_standard', $data));
In this way the index method is closed.
Now, we see the validate method, this is how validation is done, we check whether the user has permission to modify or not. If you want to validate the form data then you can check it here as well. If there is an error then $this->error[‘warning’] is set and a warning is shown. We check whether the Paypal email is added or not. Similarly, you can check other validation here.
private function validate() { if (!$this->user->hasPermission('modify', 'extension/payment/paypal_standard')) { $this->error['warning'] = $this->language->get('error_permission'); } if (!$this->request->post['payment_paypal_standard_email']) { $this->error['email'] = $this->language->get('error_email'); } return !$this->error; }
In this way, we write the code in the controller for the payment extension module at admin section.
Now, admin language file of Payment extension:
Let’s work on Language file admin/language/en-gb/extension/payment/paypal_standard.php, let’s define some variables which are needed for the Paypal standard payment extension:
https://github.com/rupaknepali/Opencart-free-modules/blob/master/paypal-standard-opencart-extension/upload/admin/language/en-gb/extension/payment/paypal_standard.php
'; $_['text_authorization']= 'Authorization'; $_['text_sale'] = 'Sale'; // Entry $_['entry_email'] = 'E-Mail'; $_['entry_test'] = 'Sandbox Mode'; $_['entry_transaction'] = 'Transaction Method'; $_['entry_debug'] = 'Debug Mode'; $_['entry_total']. = 'Total'; $_['entry_canceled_reversal_status'] = 'Canceled Reversal Status'; $_['entry_completed_status'] = 'Completed Status'; $_['entry_denied_status'] = 'Denied Status'; $_['entry_expired_status'] = 'Expired Status'; $_['entry_failed_status'] = 'Failed Status'; $_['entry_pending_status'] = 'Pending Status'; $_['entry_processed_status'] = 'Processed Status'; $_['entry_refunded_status'] = 'Refunded Status'; $_['entry_reversed_status'] = 'Reversed Status'; $_['entry_voided_status'] = 'Voided Status'; $_['entry_geo_zone'] = 'Geo Zone'; $_['entry_status'] = 'Status'; $_['entry_sort_order'] = 'Sort Order'; // Tab $_['tab_general'] = 'General'; $_['tab_order_status'] = 'Order Status'; // Help $_['help_test'] = 'Use the live or testing (sandbox) gateway server to process transactions?'; $_['help_debug'] = 'Logs additional information to the system log'; $_['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 payment PayPal Payments Standard!'; $_['error_email'] = 'E-Mail required!';
In the above code, you can find the following code:
$_['text_paypal_standard']= '
';
This is the code which shows the payment logo at the payment extension listings.

Now, admin template file of Payment extension:
Third, open admin/view/template/extension/payment and create paypal_standard.twig. Here we create the form and other layouts. You can see the code here: https://github.com/rupaknepali/Opencart-free-modules/blob/master/paypal-standard-opencart-extension/upload/admin/view/template/extension/payment/paypal_standard.twig
Be sure to start the name with "payment_" for every fields name.
{{ header }}{{ column_left }} {{ footer }}
We describe some important code only as mostly they are same.
Let's start with the submit or save button code:
The button type is submitted, and form equals value needs to be the form id. The form id is form-payment that is why it is, form="form-payment", the form code is like below:
No header, no footer, no left or right column are needed on the template, with this, only the submit button is shown. Check the following code, this is to show the text saying it is only for test.
{% if testmode %}{{ text_testmode }}{% endif %}
In this way, we write the code at the catalog template of PayPal Standard, similarly way we can write for other payment extensions. Please let us know in the comment if we need to define any of the code above.
Now once the Paypal Standard is activated then it will show like below:

In this way, you can create the form in the admin section, validate the form data, validate the permission, and save the data to the database in the setting database table for the Payment extension and show it in the front. Hope you liked this article, please subscribe to our YouTube Channel for Opencart video tutorials. You can also find us on Twitter and Facebook.