Overview
Shipping methods calculate shipping costs during checkout based on order weight, dimensions, destination, and other factors.Shipping Method Structure
extension/myvendor/
├── admin/controller/shipping/myshipping.php
├── admin/language/en-gb/shipping/myshipping.php
├── admin/view/template/shipping/myshipping.twig
└── catalog/model/shipping/myshipping.php
Admin Controller
Fromadmin/controller/extension/opencart/shipping/flat.php:8:
<?php
namespace Opencart\Admin\Controller\Extension\Opencart\Shipping;
class Flat extends \Opencart\System\Engine\Controller {
public function index(): void {
$this->load->language('extension/opencart/shipping/flat');
$this->document->setTitle($this->language->get('heading_title'));
$data['save'] = $this->url->link('extension/opencart/shipping/flat.save', 'user_token=' . $this->session->data['user_token']);
$data['back'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=shipping');
$data['shipping_flat_cost'] = $this->config->get('shipping_flat_cost');
// Tax Class
$this->load->model('localisation/tax_class');
$data['shipping_flat_tax_class_id'] = (int)$this->config->get('shipping_flat_tax_class_id');
$data['tax_classes'] = $this->model_localisation_tax_class->getTaxClasses();
// Geo Zone
$this->load->model('localisation/geo_zone');
$data['shipping_flat_geo_zone_id'] = $this->config->get('shipping_flat_geo_zone_id');
$data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
$data['shipping_flat_status'] = $this->config->get('shipping_flat_status');
$data['shipping_flat_sort_order'] = $this->config->get('shipping_flat_sort_order');
$this->response->setOutput($this->load->view('extension/opencart/shipping/flat', $data));
}
public function save(): void {
$this->load->language('extension/opencart/shipping/flat');
$json = [];
if (!$this->user->hasPermission('modify', 'extension/opencart/shipping/flat')) {
$json['error'] = $this->language->get('error_permission');
}
if (!$json) {
$this->load->model('setting/setting');
$this->model_setting_setting->editSetting('shipping_flat', $this->request->post);
$json['success'] = $this->language->get('text_success');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
}
Shipping Model
Catalog model calculates shipping rates:<?php
namespace Opencart\Catalog\Model\Extension\Myvendor\Shipping;
class Myshipping extends \Opencart\System\Engine\Model {
/**
* Get Quote
*
* @param array $address Shipping address
*
* @return array Quote with rates
*/
public function getQuote(array $address): array {
$this->load->language('extension/myvendor/shipping/myshipping');
// Check if enabled for this geo zone
if ($this->config->get('shipping_myshipping_geo_zone_id')) {
$this->load->model('localisation/zone');
$zone_to_geo_zones = $this->model_localisation_zone->getZoneToGeoZones();
$match = false;
foreach ($zone_to_geo_zones as $zone_to_geo_zone) {
if ($zone_to_geo_zone['zone_id'] == $address['zone_id'] &&
$zone_to_geo_zone['geo_zone_id'] == $this->config->get('shipping_myshipping_geo_zone_id')) {
$match = true;
break;
}
}
if (!$match) {
return [];
}
}
// Calculate shipping cost
$cost = $this->calculateCost($address);
$quote_data = [];
$quote_data['myshipping'] = [
'code' => 'myshipping.myshipping',
'name' => $this->language->get('text_description'),
'cost' => $cost,
'tax_class_id' => $this->config->get('shipping_myshipping_tax_class_id'),
'text' => $this->currency->format(
$this->tax->calculate($cost, $this->config->get('shipping_myshipping_tax_class_id'), $this->config->get('config_tax')),
$this->session->data['currency']
)
];
return [
'code' => 'myshipping',
'name' => $this->language->get('heading_title'),
'quote' => $quote_data,
'sort_order' => $this->config->get('shipping_myshipping_sort_order'),
'error' => false
];
}
/**
* Calculate shipping cost based on cart and address
*
* @param array $address
*
* @return float
*/
private function calculateCost(array $address): float {
// Get cart weight
$weight = $this->cart->getWeight();
// Base cost
$cost = (float)$this->config->get('shipping_myshipping_base_cost');
// Add weight-based cost
$cost_per_kg = (float)$this->config->get('shipping_myshipping_cost_per_kg');
$cost += $weight * $cost_per_kg;
// Add distance-based cost (if applicable)
if ($address['country_id'] != $this->config->get('config_country_id')) {
$cost += (float)$this->config->get('shipping_myshipping_international_surcharge');
}
return $cost;
}
}
Real-Time Rate Calculation
For API-based shipping (UPS, FedEx, etc.):private function getRealTimeRates(array $address): array {
// Prepare package dimensions
$package = [
'weight' => $this->cart->getWeight(),
'length' => 10,
'width' => 10,
'height' => 10
];
// API request
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.shippingprovider.com/rates');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode([
'origin' => [
'postal_code' => $this->config->get('config_postcode'),
'country_code' => $this->config->get('config_country_code')
],
'destination' => [
'postal_code' => $address['postcode'],
'country_code' => $address['iso_code_2']
],
'package' => $package
]));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->config->get('shipping_myshipping_api_key')
]);
$response = curl_exec($curl);
curl_close($curl);
$rates = json_decode($response, true);
$quote_data = [];
if (isset($rates['services'])) {
foreach ($rates['services'] as $service) {
$code = 'myshipping.' . $service['service_code'];
$quote_data[$code] = [
'code' => $code,
'name' => $service['service_name'],
'cost' => $service['total_cost'],
'tax_class_id' => $this->config->get('shipping_myshipping_tax_class_id'),
'text' => $this->currency->format($service['total_cost'], $this->session->data['currency'])
];
}
}
return $quote_data;
}
Multiple Service Levels
Offer different shipping speeds:public function getQuote(array $address): array {
$quote_data = [];
// Standard shipping
$quote_data['standard'] = [
'code' => 'myshipping.standard',
'name' => 'Standard Shipping (5-7 days)',
'cost' => 10.00,
'tax_class_id' => $this->config->get('shipping_myshipping_tax_class_id'),
'text' => '$10.00'
];
// Express shipping
$quote_data['express'] = [
'code' => 'myshipping.express',
'name' => 'Express Shipping (2-3 days)',
'cost' => 25.00,
'tax_class_id' => $this->config->get('shipping_myshipping_tax_class_id'),
'text' => '$25.00'
];
// Overnight shipping
$quote_data['overnight'] = [
'code' => 'myshipping.overnight',
'name' => 'Overnight Shipping',
'cost' => 50.00,
'tax_class_id' => $this->config->get('shipping_myshipping_tax_class_id'),
'text' => '$50.00'
];
return [
'code' => 'myshipping',
'name' => 'My Shipping',
'quote' => $quote_data,
'sort_order' => $this->config->get('shipping_myshipping_sort_order'),
'error' => false
];
}
Next Steps
Creating Themes
Build custom themes
Cart Library
Work with cart data

