cdmanager/magento-min-order-fee

Magento 2 module that displays a minimum order fee as a separate total row on orders, invoices and credit memos, including admin, storefront, emails and PDFs. The fee itself is calculated and persisted by an external system.

Maintainers

Package info

github.com/cdmanager/magento-min-order-fee

Type:magento2-module

pkg:composer/cdmanager/magento-min-order-fee

Transparency log

Statistics

Installs: 10

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.1 2026-07-22 16:48 UTC

This package is auto-updated.

Last update: 2026-07-22 16:53:26 UTC


README

Latest Stable Version Total Downloads License

A Magento 2 module that shows a "Small Order Fee" as a separate total row on orders, invoices and credit memos — in the admin panel, on the storefront, in sales emails and in invoice/credit memo PDFs.

The module is designed for setups where orders are created outside the Magento checkout (e.g. written directly to the Magento database by an external backend). It therefore does not calculate the fee; it only:

  1. Schema — adds fee columns to sales_order, sales_invoice and sales_creditmemo.
  2. Display — renders the fee row between Subtotal and Grand Total on admin order/invoice/credit memo screens, storefront order view/print, order emails and PDFs.
  3. Consistency — registers invoice and credit memo total collectors so that invoices/credit memos created in the admin include the fee in their grand_total.
  4. API — exposes the fee via extension attributes on the order, invoice and credit memo REST/SOAP APIs.

Requirements

  • Magento 2.3.x / 2.4.x (tested on 2.4.7)
  • PHP 7.4+

Installation

Via Composer (Packagist)

In your Magento root directory:

composer require cdmanager/magento-min-order-fee

Via Composer (directly from GitHub)

If the package is not (yet) available on Packagist, add the repository to your Magento project's composer.json first:

composer config repositories.magento-min-order-fee vcs https://github.com/cdmanager/magento-min-order-fee
composer require cdmanager/magento-min-order-fee

Enable the module

bin/magento module:enable Chefsdeal_MinOrderFee
bin/magento setup:upgrade
bin/magento setup:di:compile   # production mode
bin/magento cache:flush

setup:upgrade applies the declarative schema (etc/db_schema.xml) and creates the fee columns.

Data contract

The external system that creates orders must populate the following columns on sales_order:

Column Type Description
min_order_fee decimal(20,4) Total fee in order currency
base_min_order_fee decimal(20,4) Total fee in base currency
min_order_fee_details text (JSON) Optional per-brand breakdown, e.g. [{"brand_id":1,"label":"Small Order Fee for Winco","amount":25.0}]

Rules:

  • The fee is not an order item. sales_order.subtotal contains products only; grand_total includes the fee:

    grand_total = subtotal + shipping + tax − discount + min_order_fee
    
  • The fee is tax-free — it must not affect tax_amount.

  • In a single-currency setup, min_order_fee == base_min_order_fee.

Invoices and credit memos

The module's total collectors only run inside Magento's collectTotals() flow (admin "Invoice"/"Credit Memo" buttons, REST API creation, payment-capture auto-invoicing). In that flow the collector derives the fee from sales_order, writes the sales_invoice / sales_creditmemo columns and adds the fee to the document's grand_total — do not pre-fill the columns there.

If the external system writes sales_invoice / sales_creditmemo rows directly to the database, collectTotals() never runs, so it must populate the columns itself:

  • Invoice: copy min_order_fee / base_min_order_fee from the order. Do not add the fee to the invoice grand_total again — the order-level grand_total being copied already includes it. Missing columns only break the display (no fee row on invoice view/PDF); the totals stay correct.
  • Credit memo: depends on the refund policy. If the fee is refundable, copy the remaining fee (order fee − fee already refunded on other credit memos) and include it in the credit memo grand_total. If the fee is non-refundable, write an explicit 0 so the intent is visible instead of a silent NULL.
  • ⚠️ Never combine both paths: writing the columns directly and letting a collector run on the same document double-counts the fee in grand_total.

The breakdown tooltip falls back to the order's min_order_fee_details, so invoices/credit memos don't need a details column.

Verification

After deploying:

  1. Check that the columns exist: SHOW COLUMNS FROM sales_order LIKE 'min\_order\_fee%'.
  2. Create an order with a fee via the external backend; verify that the "Small Order Fee" row appears between Subtotal and Grand Total on the admin order view and that grand_total reconciles.
  3. Create an invoice in the admin → the fee row appears in the invoice totals and grand_total matches the order.
  4. Create a full/partial credit memo → the fee appears in the credit memo totals and is not double-counted (order fee − already refunded).
  5. Verify the fee row in the order confirmation email and the invoice PDF.
  6. For multi-brand orders, hover over the row label → the tooltip shows the per-brand breakdown from min_order_fee_details.

File map

├── registration.php
├── etc/
│   ├── module.xml
│   ├── db_schema.xml                      # fee columns
│   ├── db_schema_whitelist.json
│   ├── extension_attributes.xml           # order/invoice/creditmemo API fields
│   ├── sales.xml                          # invoice & creditmemo total collectors
│   └── config.xml                         # PDF (invoice/creditmemo) total row
├── Model/Total/
│   ├── Invoice/MinOrderFee.php            # adds the fee to invoice grand_total
│   └── Creditmemo/MinOrderFee.php         # adds the fee to creditmemo grand_total
├── Block/
│   ├── Adminhtml/Totals/MinOrderFee.php   # admin order/invoice/creditmemo totals
│   └── Order/Totals/MinOrderFee.php       # storefront + email totals
└── view/
    ├── adminhtml/
    │   ├── layout/                        # sales_order_view, invoice view/new, creditmemo view/new
    │   └── templates/order/totals/min_order_fee.phtml
    └── frontend/
        ├── layout/                        # sales_order_view, sales_order_print, sales_email_order_items
        └── templates/order/totals/min_order_fee.phtml

Notes

  • Email/PDF block names can be theme-dependent. The order_totals layout reference works with the standard themes; a customized theme may need extra layout handles for invoice/credit memo emails (sales_email_order_invoice_items, sales_email_order_creditmemo_items).

  • Tooltip is currently a plain title attribute (native browser tooltip). A rich tooltip requires a theme-side JS/CSS component.

  • If you add new columns, regenerate the whitelist with:

    bin/magento setup:db-declaration:generate-whitelist --module-name=Chefsdeal_MinOrderFee

License

GPL-3.0-only — see LICENSE.