重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
shipping-method-development by bagisto/agent-skills
npx skills add https://github.com/bagisto/agent-skills --skill shipping-method-development在 Bagisto 中创建自定义配送方式,可以让您根据特定的业务需求定制配送选项。无论是需要易碎品的特殊处理、快递配送选项,还是特定区域的配送规则,自定义配送方式都能为您的电子商务商店提供所需的灵活性。
在本教程中,我们将创建一个自定义快递配送方式,演示构建任何类型配送解决方案所需的所有基本概念。
在以下情况下激活此技能:
Bagisto 的配送系统围绕灵活的基于承运商的架构构建,将配置与业务逻辑分离。
| 组件 | 用途 | 位置 |
|---|---|---|
| 承运商配置 | 定义配送方式属性 | Config/carriers.php |
| 承运商类 | 包含费率计算逻辑 | Carriers/ClassName.php |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 系统配置 | 管理界面表单 | Config/system.php |
| 服务提供者 | 注册配送方式 | Providers/ServiceProvider.php |
| 配送门面 | 收集和管理费率 | Webkul\Shipping\Shipping |
mkdir -p packages/Webkul/CustomExpressShipping/src/{Carriers,Config,Providers}
文件: packages/Webkul/CustomExpressShipping/src/Config/carriers.php
<?php
return [
'custom_express_shipping' => [
'code' => 'custom_express_shipping',
'title' => 'Express Delivery (1-2 Days)',
'description' => 'Premium express shipping with tracking',
'active' => true,
'default_rate' => '19.99',
'type' => 'per_order',
'class' => 'Webkul\CustomExpressShipping\Carriers\CustomExpressShipping',
],
];
| 属性 | 类型 | 用途 | 描述 |
|---|---|---|---|
code | String | 唯一标识符 | 必须与承运商类中的数组键和 $code 属性匹配。 |
title | String | 默认显示名称 | 在结账时向客户显示(可在管理后台覆盖)。 |
description | String | 方法描述 | 配送服务的简要说明。 |
active | Boolean | 默认状态 | 配送方式是否默认启用。 |
default_rate | String/Float | 基础配送成本 | 计算前的基础配送成本。 |
type | String | 定价模型 | per_order(统一费率)或 per_unit(按件计费)。 |
class | String | 承运商类命名空间 | 您的承运商类的完整路径。 |
注意: 数组键 (
custom_express_shipping) 必须与您的承运商类中的code属性、系统配置键路径匹配,并且在整个过程中应保持一致。
文件: packages/Webkul/CustomExpressShipping/src/Carriers/CustomExpressShipping.php
<?php
namespace Webkul\CustomExpressShipping\Carriers;
use Webkul\Shipping\Carriers\AbstractShipping;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Checkout\Facades\Cart;
class CustomExpressShipping extends AbstractShipping
{
/**
* Shipping method code - must match carriers.php key.
*
* @var string
*/
protected $code = 'custom_express_shipping';
/**
* Shipping method code.
*
* @var string
*/
protected $method = 'custom_express_shipping_custom_express_shipping';
/**
* Calculate shipping rate for the current cart.
*
* @return \Webkul\Checkout\Models\CartShippingRate|false
*/
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
return $this->getRate();
}
/**
* Get shipping rate.
*
* @return \Webkul\Checkout\Models\CartShippingRate
*/
public function getRate(): CartShippingRate
{
$cart = Cart::getCart();
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->method_description = $this->getConfigData('description');
$cartShippingRate->price = 0;
$cartShippingRate->base_price = 0;
$baseRate = (float) $this->getConfigData('default_rate');
if ($this->getConfigData('type') == 'per_unit') {
foreach ($cart->items as $item) {
if ($item->getTypeInstance()->isStockable()) {
$cartShippingRate->price += core()->convertPrice($baseRate) * $item->quantity;
$cartShippingRate->base_price += $baseRate * $item->quantity;
}
}
} else {
$cartShippingRate->price = core()->convertPrice($baseRate);
$cartShippingRate->base_price = $baseRate;
}
return $cartShippingRate;
}
}
文件: packages/Webkul/CustomExpressShipping/src/Config/system.php
<?php
return [
[
'key' => 'sales.carriers.custom_express_shipping',
'name' => 'Custom Express Shipping',
'info' => 'Configure the Custom Express Shipping method settings.',
'sort' => 1,
'fields' => [
[
'name' => 'title',
'title' => 'Method Title',
'type' => 'text',
'validation' => 'required',
'channel_based' => true,
'locale_based' => true,
],
[
'name' => 'description',
'title' => 'Description',
'type' => 'textarea',
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'default_rate',
'title' => 'Base Rate',
'type' => 'text',
'validation' => 'required|numeric|min:0',
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'type',
'title' => 'Pricing Type',
'type' => 'select',
'options' => [
[
'title' => 'Per Order (Flat Rate)',
'value' => 'per_order',
],
[
'title' => 'Per Item',
'value' => 'per_unit',
],
],
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'active',
'title' => 'Enabled',
'type' => 'boolean',
'validation' => 'required',
'channel_based' => true,
'locale_based' => false,
],
],
],
];
| 属性 | 用途 | 描述 |
|---|---|---|
name | 字段标识符 | 用于存储和检索配置值。 |
title | 字段标签 | 在管理表单中显示的标签。 |
type | 输入类型 | text、textarea、boolean、select、password 等。 |
default_value | 默认设置 | 首次配置时的初始值。 |
channel_based | 多店铺支持 | 每个销售渠道可以有不同的值。 |
locale_based | 多语言支持 | 每种语言的可翻译内容。 |
validation | 字段验证 | 规则如 required、numeric、email。 |
文件: packages/Webkul/CustomExpressShipping/src/Providers/CustomExpressShippingServiceProvider.php
<?php
namespace Webkul\CustomExpressShipping\Providers;
use Illuminate\Support\ServiceProvider;
class CustomExpressShippingServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/carriers.php',
'carriers'
);
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php',
'core'
);
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot(): void
{
//
}
}
{
"autoload": {
"psr-4": {
"Webkul\\CustomExpressShipping\\": "packages/Webkul/CustomExpressShipping/src"
}
}
}
2. 更新自动加载器:
composer dump-autoload
3. 在 bootstrap/providers.php 中注册服务提供者:
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers ...
Webkul\CustomExpressShipping\Providers\CustomExpressShippingServiceProvider::class,
];
4. 清除缓存:
php artisan optimize:clear
位置: packages/Webkul/Shipping/src/Carriers/AbstractShipping.php
所有配送方式都继承自 Webkul\Shipping\Carriers\AbstractShipping:
<?php
namespace Webkul\Shipping\Carriers;
use Webkul\Shipping\Exceptions\CarrierCodeException;
abstract class AbstractShipping
{
/**
* Shipping method carrier code.
*
* @var string
*/
protected $code;
/**
* Shipping method code.
*
* @var string
*/
protected $method;
abstract public function calculate();
/**
* Checks if shipping method is available.
*
* @return array
*/
public function isAvailable()
{
return $this->getConfigData('active');
}
/**
* Returns shipping method carrier code.
*
* @return string
*/
public function getCode()
{
if (empty($this->code)) {
throw new CarrierCodeException('Carrier code should be initialized.');
}
return $this->code;
}
/**
* Return shipping method code.
*
* @return string
*/
public function getMethod()
{
if (empty($this->method)) {
$code = $this->getCode();
return $code . '_' . $code;
}
return $this->method;
}
/**
* Returns shipping method title.
*
* @return array
*/
public function getTitle()
{
return $this->getConfigData('title');
}
/**
* Returns shipping method description.
*
* @return array
*/
public function getDescription()
{
return $this->getConfigData('description');
}
/**
* Retrieve information from shipping configuration.
*
* @param string $field
* @return mixed
*/
public function getConfigData($field)
{
return core()->getConfigData('sales.carriers.' . $this->getCode() . '.' . $field);
}
}
位置: packages/Webkul/Checkout/src/Models/CartShippingRate.php
<?php
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Checkout\Contracts\CartShippingRate as CartShippingRateContract;
class CartShippingRate extends Model implements CartShippingRateContract
{
protected $fillable = [
'carrier',
'carrier_title',
'method',
'method_title',
'method_description',
'price',
'base_price',
'discount_amount',
'base_discount_amount',
'tax_percent',
'tax_amount',
'base_tax_amount',
'price_incl_tax',
'base_price_incl_tax',
'applied_tax_rate',
];
}
| 方法 | 用途 | 是否必需 |
|---|---|---|
calculate() | 计算并返回配送费率 | 是(抽象方法) |
getRate() | 构建 CartShippingRate 对象 | 否(可以内联实现) |
isAvailable() | 覆盖以实现自定义可用性检查 | 否(使用默认实现) |
packages/Webkul/Shipping/src/Carriers/FlatRate.phppackages/Webkul/Shipping/src/Carriers/Free.phppublic function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->method_description = $this->getConfigData('description');
$cartShippingRate->price = 15.99;
$cartShippingRate->base_price = 15.99;
return $cartShippingRate;
}
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cart = Cart::getCart();
$baseRate = 5.00;
$perKg = 2.50;
$price = $baseRate + ($cart->weight * $perKg);
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->price = core()->convertPrice($price);
$cartShippingRate->base_price = $price;
return $cartShippingRate;
}
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cart = Cart::getCart();
$threshold = (float) $this->getConfigData('free_shipping_threshold');
$price = $cart->sub_total >= $threshold ? 0 : (float) $this->getConfigData('default_rate');
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->price = core()->convertPrice($price);
$cartShippingRate->base_price = $price;
return $cartShippingRate;
}
位置: packages/Webkul/Shipping/src/Shipping.php
Shipping 门面管理费率的收集和处理:
class Shipping
{
public function collectRates()
{
// Iterates through all carriers and calls calculate()
// Returns grouped shipping methods with rates
}
public function getGroupedAllShippingRates()
{
// Returns rates grouped by carrier
}
public function getShippingMethods()
{
// Returns available shipping methods
}
}
packages
└── Webkul
└── CustomExpressShipping
└── src
├── Carriers
│ └── CustomExpressShipping.php # 费率计算逻辑
├── Config
│ ├── carriers.php # 配送方式定义
│ └── system.php # 管理配置
└── Providers
└── CustomExpressShippingServiceProvider.php # 注册
可以通过结账流程测试配送方式。测试:
| 文件 | 用途 |
|---|---|
packages/Webkul/Shipping/src/Carriers/AbstractShipping.php | 基础抽象类 |
packages/Webkul/Shipping/src/Carriers/FlatRate.php | 统一费率配送示例 |
packages/Webkul/Shipping/src/Carriers/Free.php | 免运费示例 |
packages/Webkul/Shipping/src/Config/carriers.php | 默认承运商配置 |
packages/Webkul/Shipping/src/Shipping.php | 配送门面 |
packages/Webkul/Checkout/src/Models/CartShippingRate.php | 配送费率模型 |
packages/Webkul/Admin/src/Config/system.php | 管理配置(承运商部分) |
$code 属性与配置数组键不匹配bootstrap/providers.php 中注册服务提供者composer dump-autoloadcore()->convertPrice() 进行多货币支持isStockable()每周安装次数
23
代码仓库
GitHub 星标数
4
首次出现
11 天前
安全审计
已安装于
opencode23
gemini-cli21
github-copilot21
codex21
kimi-cli21
amp21
Creating custom shipping methods in Bagisto allows you to tailor delivery options to meet your specific business needs. Whether you need special handling for fragile items, express delivery options, or region-specific shipping rules, custom shipping methods provide the flexibility your e-commerce store requires.
For our tutorial, we'll create a Custom Express Shipping method that demonstrates all the essential concepts you need to build any type of shipping solution.
Activate this skill when:
Bagisto's shipping system is built around a flexible carrier-based architecture that separates configuration from business logic.
| Component | Purpose | Location |
|---|---|---|
| Carriers Configuration | Defines shipping method properties | Config/carriers.php |
| Carrier Classes | Contains rate calculation logic | Carriers/ClassName.php |
| System Configuration | Admin interface forms | Config/system.php |
| Service Provider | Registers shipping method | Providers/ServiceProvider.php |
| Shipping Facade | Collects and manages rates | Webkul\Shipping\Shipping |
mkdir -p packages/Webkul/CustomExpressShipping/src/{Carriers,Config,Providers}
File: packages/Webkul/CustomExpressShipping/src/Config/carriers.php
<?php
return [
'custom_express_shipping' => [
'code' => 'custom_express_shipping',
'title' => 'Express Delivery (1-2 Days)',
'description' => 'Premium express shipping with tracking',
'active' => true,
'default_rate' => '19.99',
'type' => 'per_order',
'class' => 'Webkul\CustomExpressShipping\Carriers\CustomExpressShipping',
],
];
| Property | Type | Purpose | Description |
|---|---|---|---|
code | String | Unique identifier | Must match the array key and $code property in carrier class. |
title | String | Default display name | Shown to customers during checkout (can be overridden in admin). |
description | String | Method description | Brief explanation of the shipping service. |
Note: The array key (
custom_express_shipping) must match thecodeproperty in your carrier class, system configuration key path, and should be consistent throughout.
File: packages/Webkul/CustomExpressShipping/src/Carriers/CustomExpressShipping.php
<?php
namespace Webkul\CustomExpressShipping\Carriers;
use Webkul\Shipping\Carriers\AbstractShipping;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Checkout\Facades\Cart;
class CustomExpressShipping extends AbstractShipping
{
/**
* Shipping method code - must match carriers.php key.
*
* @var string
*/
protected $code = 'custom_express_shipping';
/**
* Shipping method code.
*
* @var string
*/
protected $method = 'custom_express_shipping_custom_express_shipping';
/**
* Calculate shipping rate for the current cart.
*
* @return \Webkul\Checkout\Models\CartShippingRate|false
*/
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
return $this->getRate();
}
/**
* Get shipping rate.
*
* @return \Webkul\Checkout\Models\CartShippingRate
*/
public function getRate(): CartShippingRate
{
$cart = Cart::getCart();
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->method_description = $this->getConfigData('description');
$cartShippingRate->price = 0;
$cartShippingRate->base_price = 0;
$baseRate = (float) $this->getConfigData('default_rate');
if ($this->getConfigData('type') == 'per_unit') {
foreach ($cart->items as $item) {
if ($item->getTypeInstance()->isStockable()) {
$cartShippingRate->price += core()->convertPrice($baseRate) * $item->quantity;
$cartShippingRate->base_price += $baseRate * $item->quantity;
}
}
} else {
$cartShippingRate->price = core()->convertPrice($baseRate);
$cartShippingRate->base_price = $baseRate;
}
return $cartShippingRate;
}
}
File: packages/Webkul/CustomExpressShipping/src/Config/system.php
<?php
return [
[
'key' => 'sales.carriers.custom_express_shipping',
'name' => 'Custom Express Shipping',
'info' => 'Configure the Custom Express Shipping method settings.',
'sort' => 1,
'fields' => [
[
'name' => 'title',
'title' => 'Method Title',
'type' => 'text',
'validation' => 'required',
'channel_based' => true,
'locale_based' => true,
],
[
'name' => 'description',
'title' => 'Description',
'type' => 'textarea',
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'default_rate',
'title' => 'Base Rate',
'type' => 'text',
'validation' => 'required|numeric|min:0',
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'type',
'title' => 'Pricing Type',
'type' => 'select',
'options' => [
[
'title' => 'Per Order (Flat Rate)',
'value' => 'per_order',
],
[
'title' => 'Per Item',
'value' => 'per_unit',
],
],
'channel_based' => true,
'locale_based' => false,
],
[
'name' => 'active',
'title' => 'Enabled',
'type' => 'boolean',
'validation' => 'required',
'channel_based' => true,
'locale_based' => false,
],
],
],
];
| Property | Purpose | Description |
|---|---|---|
name | Field identifier | Used to store and retrieve configuration values. |
title | Field label | Label displayed in the admin form. |
type | Input type | text, textarea, boolean, select, , etc. |
File: packages/Webkul/CustomExpressShipping/src/Providers/CustomExpressShippingServiceProvider.php
<?php
namespace Webkul\CustomExpressShipping\Providers;
use Illuminate\Support\ServiceProvider;
class CustomExpressShippingServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/carriers.php',
'carriers'
);
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php',
'core'
);
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot(): void
{
//
}
}
{
"autoload": {
"psr-4": {
"Webkul\\CustomExpressShipping\\": "packages/Webkul/CustomExpressShipping/src"
}
}
}
2. Update autoloader:
composer dump-autoload
3. Register service provider in bootstrap/providers.php:
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers ...
Webkul\CustomExpressShipping\Providers\CustomExpressShippingServiceProvider::class,
];
4. Clear caches:
php artisan optimize:clear
Location: packages/Webkul/Shipping/src/Carriers/AbstractShipping.php
All shipping methods extend Webkul\Shipping\Carriers\AbstractShipping:
<?php
namespace Webkul\Shipping\Carriers;
use Webkul\Shipping\Exceptions\CarrierCodeException;
abstract class AbstractShipping
{
/**
* Shipping method carrier code.
*
* @var string
*/
protected $code;
/**
* Shipping method code.
*
* @var string
*/
protected $method;
abstract public function calculate();
/**
* Checks if shipping method is available.
*
* @return array
*/
public function isAvailable()
{
return $this->getConfigData('active');
}
/**
* Returns shipping method carrier code.
*
* @return string
*/
public function getCode()
{
if (empty($this->code)) {
throw new CarrierCodeException('Carrier code should be initialized.');
}
return $this->code;
}
/**
* Return shipping method code.
*
* @return string
*/
public function getMethod()
{
if (empty($this->method)) {
$code = $this->getCode();
return $code . '_' . $code;
}
return $this->method;
}
/**
* Returns shipping method title.
*
* @return array
*/
public function getTitle()
{
return $this->getConfigData('title');
}
/**
* Returns shipping method description.
*
* @return array
*/
public function getDescription()
{
return $this->getConfigData('description');
}
/**
* Retrieve information from shipping configuration.
*
* @param string $field
* @return mixed
*/
public function getConfigData($field)
{
return core()->getConfigData('sales.carriers.' . $this->getCode() . '.' . $field);
}
}
Location: packages/Webkul/Checkout/src/Models/CartShippingRate.php
<?php
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Checkout\Contracts\CartShippingRate as CartShippingRateContract;
class CartShippingRate extends Model implements CartShippingRateContract
{
protected $fillable = [
'carrier',
'carrier_title',
'method',
'method_title',
'method_description',
'price',
'base_price',
'discount_amount',
'base_discount_amount',
'tax_percent',
'tax_amount',
'base_tax_amount',
'price_incl_tax',
'base_price_incl_tax',
'applied_tax_rate',
];
}
| Method | Purpose | Required |
|---|---|---|
calculate() | Calculate and return shipping rate | Yes (abstract) |
getRate() | Build CartShippingRate object | No (can be inline) |
isAvailable() | Override for custom availability | No (uses default) |
packages/Webkul/Shipping/src/Carriers/FlatRate.phppackages/Webkul/Shipping/src/Carriers/Free.phppublic function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->method_description = $this->getConfigData('description');
$cartShippingRate->price = 15.99;
$cartShippingRate->base_price = 15.99;
return $cartShippingRate;
}
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cart = Cart::getCart();
$baseRate = 5.00;
$perKg = 2.50;
$price = $baseRate + ($cart->weight * $perKg);
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->price = core()->convertPrice($price);
$cartShippingRate->base_price = $price;
return $cartShippingRate;
}
public function calculate()
{
if (! $this->isAvailable()) {
return false;
}
$cart = Cart::getCart();
$threshold = (float) $this->getConfigData('free_shipping_threshold');
$price = $cart->sub_total >= $threshold ? 0 : (float) $this->getConfigData('default_rate');
$cartShippingRate = new CartShippingRate;
$cartShippingRate->carrier = $this->getCode();
$cartShippingRate->carrier_title = $this->getConfigData('title');
$cartShippingRate->method = $this->getMethod();
$cartShippingRate->method_title = $this->getConfigData('title');
$cartShippingRate->price = core()->convertPrice($price);
$cartShippingRate->base_price = $price;
return $cartShippingRate;
}
Location: packages/Webkul/Shipping/src/Shipping.php
The Shipping facade manages rate collection and processing:
class Shipping
{
public function collectRates()
{
// Iterates through all carriers and calls calculate()
// Returns grouped shipping methods with rates
}
public function getGroupedAllShippingRates()
{
// Returns rates grouped by carrier
}
public function getShippingMethods()
{
// Returns available shipping methods
}
}
packages
└── Webkul
└── CustomExpressShipping
└── src
├── Carriers
│ └── CustomExpressShipping.php # Rate calculation logic
├── Config
│ ├── carriers.php # Shipping method definition
│ └── system.php # Admin configuration
└── Providers
└── CustomExpressShippingServiceProvider.php # Registration
Shipping methods can be tested through the checkout flow. Test:
| File | Purpose |
|---|---|
packages/Webkul/Shipping/src/Carriers/AbstractShipping.php | Base abstract class |
packages/Webkul/Shipping/src/Carriers/FlatRate.php | Flat rate shipping example |
packages/Webkul/Shipping/src/Carriers/Free.php | Free shipping example |
packages/Webkul/Shipping/src/Config/carriers.php | Default carriers config |
packages/Webkul/Shipping/src/Shipping.php | Shipping facade |
$code property with config array keybootstrap/providers.phpcomposer dump-autoload after adding packagecore()->convertPrice() for multi-currency supportisStockable() for per-item calculationsWeekly Installs
23
Repository
GitHub Stars
4
First Seen
11 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode23
gemini-cli21
github-copilot21
codex21
kimi-cli21
amp21
WordPress插件开发指南:架构、安全、设置API与生命周期管理
1,400 周安装
LobeHub 测试指南:Vitest 单元测试、集成测试与 Mock 模式最佳实践
674 周安装
Laravel 12 最佳实践指南:29条规则构建可扩展应用
673 周安装
产品需求文档生成器 | AI产品负责人Sarah | PRD质量评分与迭代优化工具
670 周安装
Slack API 操作工具 - 消息管理、回应、置顶与成员信息查询 | OpenClaw 机器人集成
695 周安装
BibiGPT AI视频音频摘要工具:CLI与OpenAPI双模式,一键生成Markdown/JSON摘要
689 周安装
AI 产品需求文档生成器 | 自动撰写 PRD 和功能规格说明书工具
693 周安装
active| Boolean |
| Default status |
| Whether the shipping method is enabled by default. |
default_rate | String/Float | Base shipping cost | Base shipping cost before calculations. |
type | String | Pricing model | per_order (flat rate) or per_unit (per item). |
class | String | Carrier class namespace | Full path to your carrier class. |
passworddefault_value | Default setting | Initial value when first configured. |
channel_based | Multi-store support | Different values per sales channel. |
locale_based | Multi-language support | Translatable content per language. |
validation | Field validation | Rules like required, numeric, email. |
packages/Webkul/Checkout/src/Models/CartShippingRate.php| Shipping rate model |
packages/Webkul/Admin/src/Config/system.php | Admin config (carrier sections) |