This Opencart tutorial shows how to change and customize emails send out to the store administrator when they get the new order in the OpenCart store. Normally Opencart just sends an email with fewer details like below:
You have received an order.
Order ID: 1088
Date Added: 11/02/2019
Order Status: Complete
Products
1x .... $0.00
Order Totals
Sub-Total: $0.00
Total: $0.00
Let's change that email to send full details like the one that customers get.

Open catalog/controller/mail/order.php and remove the alert method and replace it with the below alert method.
// Admin Alert Mail
public function alert(&$route, &$args) {
if (isset($args[0])) {
$order_id = $args[0];
} else {
$order_id = 0;
}
if (isset($args[1])) {
$order_status_id = $args[1];
} else {
$order_status_id = 0;
}
if (isset($args[2])) {
$comment = $args[2];
} else {
$comment = '';
}
if (isset($args[3])) {
$notify = $args[3];
} else {
$notify = '';
}
$order_info = $this->model_checkout_order->getOrder($order_id);
if ($order_info && !$order_info['order_status_id'] && $order_status_id && in_array('order', (array)$this->config->get('config_mail_alert'))) {
// Check for any downloadable products
$download_status = false;
$order_products = $this->model_checkout_order->getOrderProducts($order_info['order_id']);
foreach ($order_products as $order_product) {
// Check if there are any linked downloads
$product_download_query = $this->db->query("SELECT COUNT(*) AS total FROM `" . DB_PREFIX . "product_to_download` WHERE product_id = '" . (int)$order_product['product_id'] . "'");
if ($product_download_query->row['total']) {
$download_status = true;
}
}
// Load the language for any mails that might be required to be sent out
$language = new Language($order_info['language_code']);
$language->load($order_info['language_code']);
$language->load('mail/order_add');
$this->load->language('mail/order_alert');
// HTML Mail
$data['title'] = sprintf($language->get('text_subject'), $order_info['store_name'], $order_info['order_id']);
$data['text_greeting'] = sprintf($language->get('text_greeting'), $order_info['store_name']);
$data['text_link'] = $language->get('text_link');
$data['text_download'] = $language->get('text_download');
$data['text_order_detail'] = $language->get('text_order_detail');
$data['text_instruction'] = $language->get('text_instruction');
$data['text_order_id'] = $language->get('text_order_id');
$data['text_date_added'] = $language->get('text_date_added');
$data['text_payment_method'] = $language->get('text_payment_method');
$data['text_shipping_method'] = $language->get('text_shipping_method');
$data['text_email'] = $language->get('text_email');
$data['text_telephone'] = $language->get('text_telephone');
$data['text_ip'] = $language->get('text_ip');
$data['text_order_status'] = $language->get('text_order_status');
$data['text_payment_address'] = $language->get('text_payment_address');
$data['text_shipping_address'] = $language->get('text_shipping_address');
$data['text_product'] = $language->get('text_product');
$data['text_model'] = $language->get('text_model');
$data['text_quantity'] = $language->get('text_quantity');
$data['text_price'] = $language->get('text_price');
$data['text_total'] = $language->get('text_total');
$data['text_footer'] = $language->get('text_footer');
$data['logo'] = $order_info['store_url'] . 'image/' . $this->config->get('config_logo');
$data['store_name'] = $order_info['store_name'];
$data['store_url'] = $order_info['store_url'];
$data['customer_id'] = $order_info['customer_id'];
$data['link'] = $order_info['store_url'] . 'index.php?route=account/order/info&order_id=' . $order_info['order_id'];
if ($download_status) {
$data['download'] = $order_info['store_url'] . 'index.php?route=account/download';
} else {
$data['download'] = '';
}
$data['order_id'] = $order_info['order_id'];
$data['date_added'] = date($language->get('date_format_short'), strtotime($order_info['date_added']));
$data['payment_method'] = $order_info['payment_method'];
$data['shipping_method'] = $order_info['shipping_method'];
$data['email'] = $order_info['email'];
$data['telephone'] = $order_info['telephone'];
$data['ip'] = $order_info['ip'];
$order_status_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_status WHERE order_status_id = '" . (int)$order_status_id . "' AND language_id = '" . (int)$order_info['language_id'] . "'");
if ($order_status_query->num_rows) {
$data['order_status'] = $order_status_query->row['name'];
} else {
$data['order_status'] = '';
}
if ($comment && $notify) {
$data['comment'] = nl2br($comment);
} else {
$data['comment'] = '';
}
if ($order_info['payment_address_format']) {
$format = $order_info['payment_address_format'];
} else {
$format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
$find = array(
'{firstname}',
'{lastname}',
'{company}',
'{address_1}',
'{address_2}',
'{city}',
'{postcode}',
'{zone}',
'{zone_code}',
'{country}'
);
$replace = array(
'firstname' => $order_info['payment_firstname'],
'lastname' => $order_info['payment_lastname'],
'company' => $order_info['payment_company'],
'address_1' => $order_info['payment_address_1'],
'address_2' => $order_info['payment_address_2'],
'city' => $order_info['payment_city'],
'postcode' => $order_info['payment_postcode'],
'zone' => $order_info['payment_zone'],
'zone_code' => $order_info['payment_zone_code'],
'country' => $order_info['payment_country']
);
$data['payment_address'] = str_replace(array("\r\n", "\r", "\n"), '
', preg_replace(array("/\s\s+/", "/\r\r+/", "/\n\n+/"), '
', trim(str_replace($find, $replace, $format))));
if ($order_info['shipping_address_format']) {
$format = $order_info['shipping_address_format'];
} else {
$format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
$find = array(
'{firstname}',
'{lastname}',
'{company}',
'{address_1}',
'{address_2}',
'{city}',
'{postcode}',
'{zone}',
'{zone_code}',
'{country}'
);
$replace = array(
'firstname' => $order_info['shipping_firstname'],
'lastname' => $order_info['shipping_lastname'],
'company' => $order_info['shipping_company'],
'address_1' => $order_info['shipping_address_1'],
'address_2' => $order_info['shipping_address_2'],
'city' => $order_info['shipping_city'],
'postcode' => $order_info['shipping_postcode'],
'zone' => $order_info['shipping_zone'],
'zone_code' => $order_info['shipping_zone_code'],
'country' => $order_info['shipping_country']
);
$data['shipping_address'] = str_replace(array("\r\n", "\r", "\n"), '
', preg_replace(array("/\s\s+/", "/\r\r+/", "/\n\n+/"), '
', trim(str_replace($find, $replace, $format))));
$this->load->model('tool/upload');
// Products
$data['products'] = array();
foreach ($order_products as $order_product) {
$option_data = array();
$order_options = $this->model_checkout_order->getOrderOptions($order_info['order_id'], $order_product['order_product_id']);
foreach ($order_options as $order_option) {
if ($order_option['type'] != 'file') {
$value = $order_option['value'];
} else {
$upload_info = $this->model_tool_upload->getUploadByCode($order_option['value']);
if ($upload_info) {
$value = $upload_info['name'];
} else {
$value = '';
}
}
$option_data[] = array(
'name' => $order_option['name'],
'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
);
}
$data['products'][] = array(
'name' => $order_product['name'],
'model' => $order_product['model'],
'option' => $option_data,
'quantity' => $order_product['quantity'],
'price' => $this->currency->format($order_product['price'] + ($this->config->get('config_tax') ? $order_product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']),
'total' => $this->currency->format($order_product['total'] + ($this->config->get('config_tax') ? ($order_product['tax'] * $order_product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value'])
);
}
// Vouchers
$data['vouchers'] = array();
$order_vouchers = $this->model_checkout_order->getOrderVouchers($order_info['order_id']);
foreach ($order_vouchers as $order_voucher) {
$data['vouchers'][] = array(
'description' => $order_voucher['description'],
'amount' => $this->currency->format($order_voucher['amount'], $order_info['currency_code'], $order_info['currency_value']),
);
}
// Order Totals
$data['totals'] = array();
$order_totals = $this->model_checkout_order->getOrderTotals($order_info['order_id']);
foreach ($order_totals as $order_total) {
$data['totals'][] = array(
'title' => $order_total['title'],
'text' => $this->currency->format($order_total['value'], $order_info['currency_code'], $order_info['currency_value']),
);
}
$this->load->model('setting/setting');
$from = $this->model_setting_setting->getSettingValue('config_email', $order_info['store_id']);
if (!$from) {
$from = $this->config->get('config_email');
}
$mail = new Mail($this->config->get('config_mail_engine'));
$mail->parameter = $this->config->get('config_mail_parameter');
$mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname');
$mail->smtp_username = $this->config->get('config_mail_smtp_username');
$mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8');
$mail->smtp_port = $this->config->get('config_mail_smtp_port');
$mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout');
$mail->setTo($this->config->get('config_email'));
$mail->setFrom($this->config->get('config_email'));
$mail->setSender(html_entity_decode($order_info['store_name'], ENT_QUOTES, 'UTF-8'));
$mail->setSubject(html_entity_decode(sprintf($this->language->get('text_subject'), $this->config->get('config_name'), $order_info['order_id']), ENT_QUOTES, 'UTF-8'));
$mail->setHtml($this->load->view('mail/order_alert', $data));
$mail->send();
// Send to additional alert emails
$emails = explode(',', $this->config->get('config_mail_alert_email'));
foreach ($emails as $email) {
if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$mail->setTo($email);
$mail->send();
}
}
}
}
Then go to catalog/view/theme/YOUR_THEME/template/mail/order_mail.twig and remove all the code and replace with the following codes:
{{ title }}
{{ text_greeting }}
{% if download %}
{{ text_download }}
<{% endif %}
{{ text_order_detail }}
{{ text_order_id }} {{ order_id }}
{{ text_date_added }} {{ date_added }}
{{ text_payment_method }} {{ payment_method }}
{% if shipping_method %} {{ text_shipping_method }} {{ shipping_method }}
{% endif %}
{{ text_email }} {{ email }}
{{ text_telephone }} {{ telephone }}
{{ text_ip }} {{ ip }}
{{ text_order_status }} {{ order_status }}
{% if comment %}
{{ text_instruction }}
{{ comment }}
{% endif %}
{{ text_payment_address }}
{% if shipping_address %}
{{ text_shipping_address }}
{% endif %}
{{ payment_address }}
{% if shipping_address %}
{{ shipping_address }}
{% endif %}
{{ text_product }}
{{ text_model }}
{{ text_quantity }}
{{ text_price }}
{{ text_total }}
{% for product in products %}
{{ product.name }}
{% for option in product.option %}
- {{ option.name }}: {{ option.value }}{% endfor %}
{{ product.model }}
{{ product.quantity }}
{{ product.price }}
{{ product.total }}
{% endfor %}
{% for voucher in vouchers %}
{{ voucher.description }}
1
{{ voucher.amount }}
{{ voucher.amount }}
{% endfor %}
{% for total in totals %}
{{ total.title }}:
{{ total.text }}
{% endfor %}
{{ text_footer }}
With these changes, you can get the customized full detail email for Admin as well.
If you want to change the email design for the affiliate alert, affiliate welcome email, forgotten password email, order notification to the customer, order alert to store administrator, edit order alert, register alert, register notification to the customer, transaction alert, voucher alert, you can change them at catalog/view/theme/YOUR_TEME/template/mail where you can change your design as per your need.
Let us know if you find any difficulties or need any help from us. Likewise, you can see other Opencart tips and tricks.