Skip to content
  1. Extras
  2. MiniShop3
  3. Manager interface
  4. Settings
  5. Deliveries

Delivery methods ​

Settings → Deliveries

Open Extras → MiniShop3 → Settings → Deliveries.

Delivery fields ​

FieldTypeDescription
namestringDelivery method name
descriptiontextDescription for the customer
pricestringBase delivery cost (stored as varchar(11), cast to a number in the calculation)
weight_pricefloatCost per unit of weight
distance_pricefloatCost per unit of distance. The calculation does not use it now (reserved field)
free_delivery_amountfloatOrder total for free delivery
logostringPath to the image
positionintSort order
activeboolActive flag
classstringPHP handler class
validation_rulesJSONField validation rules
propertiesJSONJSON properties for the handler's own data

Payment linkage ​

You link each delivery method to the payment methods it needs.

  • Cash only for pickup
  • Online payment for courier delivery
  • Your own combinations for different regions

When the customer picks a delivery, the payment list is filtered.

Cost calculation ​

Delivery cost is calculated with this formula:

text
Total cost = price + (weight_price × weight)

If the order total is greater than or equal to free_delivery_amount, the delivery cost is 0.

Custom calculation ​

For a more complex rule, create your own handler class:

php
<?php
namespace MyComponent\Delivery;

use MiniShop3\Controllers\Delivery\DeliveryProviderInterface;
use MiniShop3\Model\msDelivery;
use MiniShop3\Model\msOrder;

class CustomDelivery implements DeliveryProviderInterface
{
    public function getCost(msOrder $order, msDelivery $delivery, float $cost): float
    {
        // Your calculation
        $cartCost = $order->get('cart_cost');
        $weight = $order->get('weight');

        if ($cartCost > 10000) {
            return 0; // Free from 10000 RUB
        }

        if ($weight > 5000) {
            return 500 + ($weight - 5000) * 0.1; // Surcharge for a heavy order
        }

        return 300; // Base cost
    }
}

Set the class in the class field: MyComponent\Delivery\CustomDelivery.

Order field validation ​

For each delivery method you set the required fields and the rules. A courier needs a full address. Pickup needs a phone.

Visual builder ​

Visual mode ​

  1. Click Add field
  2. Pick a field from the list (groups: Order, Address)
  3. Add validation rules for the field
  4. For rules that take a parameter, set the value

Rules show up as tags. Click the cross to remove one.

JSON mode ​

The switch opens manual JSON editing:

json
{
  "phone": "required",
  "email": "required|email",
  "city": "required|min:2",
  "street": "required|min:3",
  "building": "required"
}

In this mode you copy rules between deliveries, set a regex, and move JSON between installs.

Custom validation fields ​

Besides the standard order and address fields, you can add your own. An agreement checkbox is one example:

json
{
  "phone": "required",
  "email": "required|email",
  "agreement": "required|accepted"
}

Fields outside the standard set (agreement and others) stay on the order draft between the order/add and order/submit steps. When the order is created they go to msOnBeforeCreateOrder / msOnCreateOrder through the customFields parameter.

Checkboxes

On the storefront, checkboxes send input.checked ('1' or '0'), not a static value attribute. That is what makes the accepted rule work.

Available validation fields ​

Order fields ​

FieldDescription
order_commentOrder comment

Address fields ​

FieldDescription
first_nameFirst name
last_nameLast name
phonePhone
emailEmail
countryCountry
indexPostal code
regionRegion
cityCity
metroMetro station
streetStreet
buildingBuilding
entranceEntrance
floorFloor
roomApartment or office
commentAddress comment
text_addressFull address as text

Validation rules ​

Validation is done by the built-in PipeRuleValidator (src/Services/Validation/PipeRuleValidator.php). No external library is required. Rules are combined with |.

Basic rules ​

RuleDescription
requiredRequired field
nullableThe field may be null
presentThe field must be present, even when empty
acceptedThe value must be "yes", "on", "1", or true

Data types ​

RuleDescription
emailValid email
urlValid URL
ipIP address (v4 or v6)
ipv4IPv4 address
ipv6IPv6 address
numericNumeric value
integerInteger
booleanBoolean
arrayArray
jsonValid JSON

String rules ​

RuleDescription
alphaLetters only
alpha_numLetters and digits
alpha_dashLetters, digits, hyphen, underscore
alpha_spacesLetters and spaces
uppercaseUppercase letters only
lowercaseLowercase letters only

Rules with parameters ​

RuleDescriptionSyntax
minMinimum string length or numeric valuemin:3
maxMaximum string length or numeric valuemax:100
betweenValue inside a rangebetween:1,10
digitsExact digit countdigits:6
digits_betweenDigit count inside a rangedigits_between:4,8
inValue from a listin:pickup,courier,post
not_inValue not in the listnot_in:test,demo
sameMatches another fieldsame:email_confirm
differentDiffers from another fielddifferent:old_password
regexMatches a regular expressionregex:/^[0-9]{6}$/
extensionFile extensionextension:jpg,png
mimesFile MIME typemimes:jpg,png

Date rules ​

RuleDescriptionSyntax
dateValid date in the given formatdate:Y-m-d
afterDate after the given oneafter:2024-01-01
beforeDate before the given onebefore:2025-12-31

Conditional rules ​

RuleDescriptionSyntax
required_ifRequired when another field equals a valuerequired_if:delivery,courier
required_unlessRequired when another field is not that valuerequired_unless:delivery,pickup
required_withRequired when another field is setrequired_with:phone
required_withoutRequired when another field is not setrequired_without:email
required_with_allRequired when all of the fields are setrequired_with_all:city,street
required_without_allRequired when none of the fields are setrequired_without_all:phone,email

Configuration examples ​

Courier delivery ​

A full address is required:

json
{
  "first_name": "required|min:2",
  "last_name": "required|min:2",
  "phone": "required|regex:/^\\+?[0-9]{10,15}$/",
  "email": "required|email",
  "city": "required|min:2",
  "street": "required|min:3",
  "building": "required",
  "room": "required_if:building_type,apartment"
}

Pickup ​

The minimum needed to reach the customer:

json
{
  "first_name": "required|min:2",
  "phone": "required"
}

Postal delivery ​

A postal code and a full address are required:

json
{
  "first_name": "required",
  "last_name": "required",
  "phone": "required",
  "index": "required|digits:6",
  "region": "required",
  "city": "required",
  "street": "required",
  "building": "required"
}

Parcel locker ​

Contact details only:

json
{
  "first_name": "required",
  "phone": "required|regex:/^\\+?[0-9]{10,15}$/",
  "email": "required|email"
}

Error messages ​

The default messages are English (PipeRuleValidator::DEFAULT_MESSAGES). They do not follow the interface language. Set them through setValidationRules() / setValidationMessages() (OrderFieldManager) or through the delivery properties.

API ​

Both GET requests require the shop token: a Bearer or MS3Token header, or the ms3_token cookie. A query parameter is not accepted.

Get validation rules ​

http
GET /api/v1/order/delivery/validation-rules?delivery_id=1

Response:

json
{
  "success": true,
  "data": {
    "validation_rules": {
      "phone": "required",
      "city": "required|min:2",
      "street": "required"
    }
  }
}

Get required fields ​

http
GET /api/v1/order/delivery/required-fields?delivery_id=1

Response (a map of field to rules, only those that include required):

json
{
  "success": true,
  "data": {
    "requires": {
      "phone": "required",
      "city": "required",
      "street": "required"
    }
  }
}

These two requests refresh the order form when the delivery method changes.