working in oc 3.0.3.2 and php 7.4.33
It's a copy of the actual website with a template called nou and several extensions, but they don't really affect this particular modification.
I'm trying to add some extra fields in the delivery address (not billing address).
I've added the first field (as a test) in the delivery address for guest checkout.
Did a test order and I can see the extra field in my database - it's an extra phone number.
So far so good.
I'm now trying to display the extra phone number in the order, in the admin but I must be missing something.
I've edited the order.php for both the controller and model. As far as I can understand the way the delivery address is displayed is from the order.php in the controller - or not?
Any idea what file exactly I have to edit in order to display the extra field in the ordeR?
https://github.com/opencart/opencart/bl ... #L870-L903
So I probably did something wrong.... I'll check again I suppose :/
*** EDIT ***
arghhh.... got it.... It was a typo.
I'm keeping the thread open to post the complete solution, when I'm done, for anyone interested
The extra field is added and displayed in the orders.
My issue now, is when I try to edit the order as an admin.
The extra field is displayed in the edit order form and the entry is there.
But if I save, it disappears. Any additions are not saved in the database.
I've edited so far, admin/view/template/sale/order_Form.twig - admin/model/order/order.php - admin/controller/sale/order.php.
Any other changes are saved, just not the new field.
I've read somewhere order changes go through the front edn: catalog/controller/api/order.php and catalog/model/checkout/order.php
So I've checked these files as well. Still nothing.
Am I missing some other process or should I go look for typos again


Tworzenie sklepów internetowych | Portfolio | Cennik | O mnie
Tworzenie sklepów internetowych | Portfolio | Cennik | O mnie
I just want to display an extra phone field in the shipping address (only). I can't do that through the custom fields.
The information in order_info.twig comes from admin/controller/sale/order.php - I've already fixed that. It was typo.
I have a different issue now, when I'm trying to edit the order through the admin.
DesignCart wrote: ↑Thu Jul 17, 2025 7:20 pmOpencart supports additional fields in the order and you don't have to rummage through the files additionally. The information should display automatically. But...if you really want it on the admin side for the order details sale/order.php -> info() and sale/order_info.twig
/api/shipping.php was the file I was missing! that worked
ADD Creative wrote: ↑Fri Jul 18, 2025 2:52 amThe shipping address is saved to the session via api/shipping/address. This then get saved via api/order/edit.
Marking it as SOLVEDvourlismenos wrote: ↑Sat Jul 19, 2025 12:36 amThank you!!!
/api/shipping.php was the file I was missing! that worked
ADD Creative wrote: ↑Fri Jul 18, 2025 2:52 amThe shipping address is saved to the session via api/shipping/address. This then get saved via api/order/edit.
Got an urgent question that’s keeping you up at night? There might just be a magical inbox ready to help: khnaz35@gmail.com
Enjoy nature
khnaz35 wrote: ↑Sat Jul 19, 2025 12:12 pmMarking it as SOLVEDvourlismenos wrote: ↑Sat Jul 19, 2025 12:36 amThank you!!!
/api/shipping.php was the file I was missing! that worked
ADD Creative wrote: ↑Fri Jul 18, 2025 2:52 amThe shipping address is saved to the session via api/shipping/address. This then get saved via api/order/edit.
This is for guest checkout only at the moment, but could be applied in the registered user as well I suppose. But it might be a bit more complicated as it stores the addresses.
I wanted to add an extra telephone field in the shipping address so that local courier services can contact the recipient.
The type of field can be adjusted.
The solution can be refined a bit, but it works.
First you have to add a new column in the _order table in the database.
In my case I've added one called shipping_telephone2
Then you have to start editing files:
controller/api/order.php
look for two instances of:
Code: Select all
$order_data['shipping_company'] = $this->session->data['shipping_address']['company'];
add under it:
Code: Select all
$order_data['shipping_telephone2'] = $this->session->data['shipping_address']['telephone2'];
Code: Select all
$order_data['shipping_company'] = '';
Code: Select all
$order_data['shipping_telephone2'] = '';
look for:
Code: Select all
'company',
Code: Select all
'telephone2',
Code: Select all
'company' => $this->request->post['company'],
Code: Select all
'telephone2' => $this->request->post['telephone2'],
look for:
Code: Select all
$order_data['shipping_company'] = $this->session->data['shipping_address']['company'];
Code: Select all
$order_data['shipping_telephone2'] = $this->session->data['shipping_address']['telephone2'];
Code: Select all
$order_data['shipping_company'] = '';
Code: Select all
$order_data['shipping_telephone2'] = '';
look for:
Code: Select all
if (isset($this->session->data['shipping_address']['company'])) {
$data['company'] = $this->session->data['shipping_address']['company'];
} else {
$data['company'] = '';
}
Code: Select all
if (isset($this->session->data['shipping_address']['telephone2'])) {
$data['telephone2'] = $this->session->data['shipping_address']['telephone2'];
} else {
Code: Select all
$this->session->data['shipping_address']['company'] = $this->request->post['company'];
Code: Select all
$this->session->data['shipping_address']['telephone2'] = $this->request->post['telephone2'];
Code: Select all
catalog/controller/mail/order.php
Code: Select all
} else {
$format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
Code: Select all
} else {
$format = '{firstname} {lastname}' . "\n" . '{telephone2}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
Code: Select all
$find = array(
'{firstname}',
'{lastname}',
'{company}',
Code: Select all
$find = array(
'{firstname}',
'{lastname}',
'{company}',
'{telephone2}',
under:
Code: Select all
'company' => $order_info['shipping_company'],
Code: Select all
'telephone2' => $order_info['shipping_telephone2'],
find:
Code: Select all
$this->db->query("INSERT INTO `" . DB_PREFIX . "order` SET invoice_prefix = '" . $this->db->escape($data['invoice_prefix']) . "', store_id = '" . (int)$data['store_id'] . "', store_name = '" . $this->db->escape($data['store_name']) . "', store_url = '" . $this->db->escape($data['store_url']) . "', customer_id = '" . (int)$data['customer_id'] . "', customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']) ? json_encode($data['custom_field']) : '') . "', payment_firstname = '" . $this->db->escape($data['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($data['payment_lastname']) . "', payment_company = '" . $this->db->escape($data['payment_company']) . "', payment_address_1 = '" . $this->db->escape($data['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($data['payment_address_2']) . "', payment_city = '" . $this->db->escape($data['payment_city']) . "', payment_postcode = '" . $this->db->escape($data['payment_postcode']) . "', payment_country = '" . $this->db->escape($data['payment_country']) . "', payment_country_id = '" . (int)$data['payment_country_id'] . "', payment_zone = '" . $this->db->escape($data['payment_zone']) . "', payment_zone_id = '" . (int)$data['payment_zone_id'] . "', payment_address_format = '" . $this->db->escape($data['payment_address_format']) . "', payment_custom_field = '" . $this->db->escape(isset($data['payment_custom_field']) ? json_encode($data['payment_custom_field']) : '') . "', payment_method = '" . $this->db->escape($data['payment_method']) . "', payment_code = '" . $this->db->escape($data['payment_code']) . "', shipping_firstname = '" . $this->db->escape($data['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($data['shipping_lastname']) . "', shipping_company = '" . $this->db->escape($data['shipping_company']) . "', shipping_address_1 = '" . $this->db->escape($data['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($data['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($data['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($data['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($data['shipping_country']) . "', shipping_country_id = '" . (int)$data['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($data['shipping_zone']) . "', shipping_zone_id = '" . (int)$data['shipping_zone_id'] . "', shipping_address_format = '" . $this->db->escape($data['shipping_address_format']) . "', shipping_custom_field = '" . $this->db->escape(isset($data['shipping_custom_field']) ? json_encode($data['shipping_custom_field']) : '') . "', shipping_method = '" . $this->db->escape($data['shipping_method']) . "', shipping_code = '" . $this->db->escape($data['shipping_code']) . "', comment = '" . $this->db->escape($data['comment']) . "', total = '" . (float)$data['total'] . "', affiliate_id = '" . (int)$data['affiliate_id'] . "', commission = '" . (float)$data['commission'] . "', marketing_id = '" . (int)$data['marketing_id'] . "', tracking = '" . $this->db->escape($data['tracking']) . "', language_id = '" . (int)$data['language_id'] . "', currency_id = '" . (int)$data['currency_id'] . "', currency_code = '" . $this->db->escape($data['currency_code']) . "', currency_value = '" . (float)$data['currency_value'] . "', ip = '" . $this->db->escape($data['ip']) . "', forwarded_ip = '" . $this->db->escape($data['forwarded_ip']) . "', user_agent = '" . $this->db->escape($data['user_agent']) . "', accept_language = '" . $this->db->escape($data['accept_language']) . "', date_added = NOW(), date_modified = NOW()");
Code: Select all
$this->db->query("INSERT INTO `" . DB_PREFIX . "order` SET invoice_prefix = '" . $this->db->escape($data['invoice_prefix']) . "', store_id = '" . (int)$data['store_id'] . "', store_name = '" . $this->db->escape($data['store_name']) . "', store_url = '" . $this->db->escape($data['store_url']) . "', customer_id = '" . (int)$data['customer_id'] . "', customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']) ? json_encode($data['custom_field']) : '') . "', payment_firstname = '" . $this->db->escape($data['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($data['payment_lastname']) . "', payment_company = '" . $this->db->escape($data['payment_company']) . "', payment_address_1 = '" . $this->db->escape($data['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($data['payment_address_2']) . "', payment_city = '" . $this->db->escape($data['payment_city']) . "', payment_postcode = '" . $this->db->escape($data['payment_postcode']) . "', payment_country = '" . $this->db->escape($data['payment_country']) . "', payment_country_id = '" . (int)$data['payment_country_id'] . "', payment_zone = '" . $this->db->escape($data['payment_zone']) . "', payment_zone_id = '" . (int)$data['payment_zone_id'] . "', payment_address_format = '" . $this->db->escape($data['payment_address_format']) . "', payment_custom_field = '" . $this->db->escape(isset($data['payment_custom_field']) ? json_encode($data['payment_custom_field']) : '') . "', payment_method = '" . $this->db->escape($data['payment_method']) . "', payment_code = '" . $this->db->escape($data['payment_code']) . "', shipping_firstname = '" . $this->db->escape($data['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($data['shipping_lastname']) . "', shipping_company = '" . $this->db->escape($data['shipping_company']) . "', shipping_telephone2 = '" . $this->db->escape($data['shipping_telephone2']) . "', shipping_address_1 = '" . $this->db->escape($data['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($data['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($data['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($data['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($data['shipping_country']) . "', shipping_country_id = '" . (int)$data['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($data['shipping_zone']) . "', shipping_zone_id = '" . (int)$data['shipping_zone_id'] . "', shipping_address_format = '" . $this->db->escape($data['shipping_address_format']) . "', shipping_custom_field = '" . $this->db->escape(isset($data['shipping_custom_field']) ? json_encode($data['shipping_custom_field']) : '') . "', shipping_method = '" . $this->db->escape($data['shipping_method']) . "', shipping_code = '" . $this->db->escape($data['shipping_code']) . "', comment = '" . $this->db->escape($data['comment']) . "', total = '" . (float)$data['total'] . "', affiliate_id = '" . (int)$data['affiliate_id'] . "', commission = '" . (float)$data['commission'] . "', marketing_id = '" . (int)$data['marketing_id'] . "', tracking = '" . $this->db->escape($data['tracking']) . "', language_id = '" . (int)$data['language_id'] . "', currency_id = '" . (int)$data['currency_id'] . "', currency_code = '" . $this->db->escape($data['currency_code']) . "', currency_value = '" . (float)$data['currency_value'] . "', ip = '" . $this->db->escape($data['ip']) . "', forwarded_ip = '" . $this->db->escape($data['forwarded_ip']) . "', user_agent = '" . $this->db->escape($data['user_agent']) . "', accept_language = '" . $this->db->escape($data['accept_language']) . "', date_added = NOW(), date_modified = NOW()");
Code: Select all
$this->db->query("UPDATE `" . DB_PREFIX . "order` SET invoice_prefix = '" . $this->db->escape($data['invoice_prefix']) . "', store_id = '" . (int)$data['store_id'] . "', store_name = '" . $this->db->escape($data['store_name']) . "', store_url = '" . $this->db->escape($data['store_url']) . "', customer_id = '" . (int)$data['customer_id'] . "', customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(json_encode($data['custom_field'])) . "', payment_firstname = '" . $this->db->escape($data['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($data['payment_lastname']) . "', payment_company = '" . $this->db->escape($data['payment_company']) . "', payment_address_1 = '" . $this->db->escape($data['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($data['payment_address_2']) . "', payment_city = '" . $this->db->escape($data['payment_city']) . "', payment_postcode = '" . $this->db->escape($data['payment_postcode']) . "', payment_country = '" . $this->db->escape($data['payment_country']) . "', payment_country_id = '" . (int)$data['payment_country_id'] . "', payment_zone = '" . $this->db->escape($data['payment_zone']) . "', payment_zone_id = '" . (int)$data['payment_zone_id'] . "', payment_address_format = '" . $this->db->escape($data['payment_address_format']) . "', payment_custom_field = '" . $this->db->escape(json_encode($data['payment_custom_field'])) . "', payment_method = '" . $this->db->escape($data['payment_method']) . "', payment_code = '" . $this->db->escape($data['payment_code']) . "', shipping_firstname = '" . $this->db->escape($data['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($data['shipping_lastname']) . "', shipping_company = '" . $this->db->escape($data['shipping_company']) . "', shipping_address_1 = '" . $this->db->escape($data['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($data['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($data['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($data['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($data['shipping_country']) . "', shipping_country_id = '" . (int)$data['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($data['shipping_zone']) . "', shipping_zone_id = '" . (int)$data['shipping_zone_id'] . "', shipping_address_format = '" . $this->db->escape($data['shipping_address_format']) . "', shipping_custom_field = '" . $this->db->escape(json_encode($data['shipping_custom_field'])) . "', shipping_method = '" . $this->db->escape($data['shipping_method']) . "', shipping_code = '" . $this->db->escape($data['shipping_code']) . "', comment = '" . $this->db->escape($data['comment']) . "', total = '" . (float)$data['total'] . "', affiliate_id = '" . (int)$data['affiliate_id'] . "', commission = '" . (float)$data['commission'] . "', date_modified = NOW() WHERE order_id = '" . (int)$order_id . "'");
Code: Select all
$this->db->query("UPDATE `" . DB_PREFIX . "order` SET invoice_prefix = '" . $this->db->escape($data['invoice_prefix']) . "', store_id = '" . (int)$data['store_id'] . "', store_name = '" . $this->db->escape($data['store_name']) . "', store_url = '" . $this->db->escape($data['store_url']) . "', customer_id = '" . (int)$data['customer_id'] . "', customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', custom_field = '" . $this->db->escape(json_encode($data['custom_field'])) . "', payment_firstname = '" . $this->db->escape($data['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($data['payment_lastname']) . "', payment_company = '" . $this->db->escape($data['payment_company']) . "', payment_address_1 = '" . $this->db->escape($data['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($data['payment_address_2']) . "', payment_city = '" . $this->db->escape($data['payment_city']) . "', payment_postcode = '" . $this->db->escape($data['payment_postcode']) . "', payment_country = '" . $this->db->escape($data['payment_country']) . "', payment_country_id = '" . (int)$data['payment_country_id'] . "', payment_zone = '" . $this->db->escape($data['payment_zone']) . "', payment_zone_id = '" . (int)$data['payment_zone_id'] . "', payment_address_format = '" . $this->db->escape($data['payment_address_format']) . "', payment_custom_field = '" . $this->db->escape(json_encode($data['payment_custom_field'])) . "', payment_method = '" . $this->db->escape($data['payment_method']) . "', payment_code = '" . $this->db->escape($data['payment_code']) . "', shipping_firstname = '" . $this->db->escape($data['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($data['shipping_lastname']) . "', shipping_company = '" . $this->db->escape($data['shipping_company']) . "', shipping_telephone2 = '" . $this->db->escape($data['shipping_telephone2']) . "', shipping_address_1 = '" . $this->db->escape($data['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($data['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($data['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($data['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($data['shipping_country']) . "', shipping_country_id = '" . (int)$data['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($data['shipping_zone']) . "', shipping_zone_id = '" . (int)$data['shipping_zone_id'] . "', shipping_address_format = '" . $this->db->escape($data['shipping_address_format']) . "', shipping_custom_field = '" . $this->db->escape(json_encode($data['shipping_custom_field'])) . "', shipping_method = '" . $this->db->escape($data['shipping_method']) . "', shipping_code = '" . $this->db->escape($data['shipping_code']) . "', comment = '" . $this->db->escape($data['comment']) . "', total = '" . (float)$data['total'] . "', affiliate_id = '" . (int)$data['affiliate_id'] . "', commission = '" . (float)$data['commission'] . "', date_modified = NOW() WHERE order_id = '" . (int)$order_id . "'");
Code: Select all
'shipping_company' => $order_query->row['shipping_company'],
Code: Select all
'shipping_telephone2' => $order_query->row['shipping_telephone2'],
and add:
Code: Select all
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-shipping-telephone2">{{ entry_telephone2 }}</label>
<div class="col-sm-10">
<input type="text" name="telephone2" value="{{ telephone2 }}" placeholder="{{ entry_telephone2 }}" id="input-shipping-telephone2" class="form-control" />
</div>
</div>
In your language file catalog/language/en-gb/checkout/checkout.php you have to add:
Code: Select all
$_['entry_telephone2'] = 'Telephone - required for delivery by courier';
admin/controller/sale/order.php
under:
Code: Select all
$data['shipping_company'] = $order_info['shipping_company'];
Code: Select all
$data['shipping_telephone2'] = $order_info['shipping_telephone2'];
Code: Select all
$data['shipping_company'] = '';
Code: Select all
$data['shipping_telephone2'] = '';
Code: Select all
// Shipping Address
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}';
}
Code: Select all
// Shipping Address
if ($order_info['shipping_address_format']) {
$format = $order_info['shipping_address_format'];
} else {
$format = '{firstname} {lastname}' . "\n" . '{telephone2}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
Code: Select all
$find = array(
'{firstname}',
'{lastname}',
'{company}',
Code: Select all
$find = array(
'{firstname}',
'{lastname}',
'{telephone2}',
'{company}',
Code: Select all
'company' => $order_info['shipping_company'],
Code: Select all
'telephone2' => $order_info['shipping_telephone2'],
Code: Select all
} else {
$format = '{firstname} {lastname}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
Code: Select all
} else {
$format = '{firstname} {lastname}' . "\n" . '{telephone2}' . "\n" . '{company}' . "\n" . '{address_1}' . "\n" . '{address_2}' . "\n" . '{city} {postcode}' . "\n" . '{zone}' . "\n" . '{country}';
}
find:
Code: Select all
'shipping_company' => $order_query->row['shipping_company'],
Code: Select all
'shipping_telephone2' => $order_query->row['shipping_telephone2'],
and add:
Code: Select all
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-shipping-telephone2">{{ entry_telephone2 }}</label>
<div class="col-sm-10">
<input type="text" name="telephone2" value="{{ shipping_telephone2 }}" id="input-shipping-telephone2" class="form-control" />
</div>
</div>
also in the language file: admin/language/el-gr/sale/order.php
add:
Code: Select all
$_['entry_telephone2'] = 'Telephone';
Users browsing this forum: Semrush [Bot] and 12 guests