Drupal Commerce shipping rates: when a team needs to build it
A team needs to build shipping rates in Drupal Commerce when its store must offer more than a flat fee: several shipping methods by destination or weight, live rates from carriers, or split shipments where one order leaves in more than one parcel. The work usually starts in one of three moments: a new store that is launching its first checkout, a migration from another cart platform or an older Drupal Commerce site that has to keep its shipping logic, or a carrier change that forces existing rate rules and label handling to be rebuilt. Each moment carries different risk, so the first decision is which of these applies and what the store must do on day one.
Shipping in Drupal Commerce is handled by Commerce Shipping, which assigns shipping methods to orders, calculates rates and creates shipments, along with carrier integrations that fetch live quotes. Both are contributed projects hosted on Drupal.org and licensed under GPL-2.0-or-later, so the licence costs nothing, but the modules, their stable release status and their compatibility with your Drupal core and Commerce versions must be confirmed before you commit. Check the current project pages and release notes for the carrier modules you need, because some carrier integrations are maintained by smaller teams and their support for your Drupal version may differ from Commerce Shipping itself.
The cost of this work depends on the rules a store needs, the number of carriers, how many products have unusual packing or dimensions, and what the existing order data looks like after a migration. This section does not give a price. When you ask for a quote, ask the partner to list the shipping methods, carrier accounts, rate sources and checkout screens in writing, and to separate one-time build work from recurring items such as carrier account fees, module updates and rate table maintenance, which you will pay for after launch. Confirm carrier account terms directly with each carrier, since those are outside the scope of the Drupal build.
What Commerce Shipping does in a Drupal store
Commerce Shipping gives a Drupal Commerce store its shipping model: methods, rates, profiles, addresses and shipments. These pieces connect at checkout, where the customer's address and the order contents determine which options are offered and what they cost. Confirm each capability against the exact Commerce Shipping release you plan to run.
Shipping methods and their scope
A shipping method is the option a customer selects at checkout, such as ground or express delivery. Each method is configured with the stores and conditions where it applies. Map your delivery options to methods before the build starts, then confirm in the module documentation which conditions the release supports and whether any need custom code.
Rate calculation through rate plugins
Rates are produced by rate plugins attached to a shipping method. Flat rates, per-item charges and carrier-calculated rates need different plugins, and each plugin takes its own settings. Ask your team which rate logic the business needs, then confirm which plugins ship with the release and which must be built or added from contributed projects.
Shipping profiles and checkout addresses
Shipping profiles hold the shipping address that rates are calculated against, and the checkout pane collects that address from the customer. Rates usually change when the address changes, so test the recalculation path with several destinations, including incomplete or invalid addresses. Confirm how the release handles address formats for each country you ship to.
Shipment entities per order
Commerce Shipping records each dispatch as a shipment entity attached to an order. A single order can need more than one shipment when items ship from different locations or on different dates. Decide early whether split shipments are in scope, and check how shipments interact with your stock and fulfillment process, including who creates them and where tracking numbers are stored.
Carrier integrations as separate work
Commerce Shipping defines the shipping model but does not by itself connect to a carrier's live rate or label services. Live quotes, label creation and tracking usually come from contributed or custom integrations. Confirm the carrier's account terms, API access and rate limits with the carrier, and check each integration module's release status before you commit to it.
Version alignment with Drupal core
Commerce Shipping must match the Drupal core version of your site, and the core major version sets the PHP floor. Drupal 11 is the current major version, and Drupal 11 requires PHP 8.3 or later. Check the Commerce Shipping release notes against your core version and plan the upgrade path before you choose a release.
Which shipping rate model fits your catalog
This table compares the main ways Drupal Commerce can calculate shipping cost, from flat fees to live carrier quotes and manual rates. Read each row for the catalog shape it suits and the ongoing work it creates, then use the final row to decide when to show rates at checkout versus after address entry.
| Rate model | Best fit | Operational cost to keep running |
|---|---|---|
| Flat rate per order or per item | Small catalogs with uniform parcels and one or two shipping zones | Lowest upkeep, but margin erodes when real carrier costs change and the flat fee is not revisited |
| Weight or price based tables | Catalogs with a known range of product weights and predictable order values | Table maintenance by someone who owns carrier tariffs, plus retesting edge bands at each change |
| Per-item rules | Mixed catalogs where bulky, fragile or oversized products need their own charge | Rules multiply quickly, so each new product class needs a rule review and a checkout test |
| Live carrier quotes | Multi-carrier stores that need current prices and service levels from the carrier | Carrier account, API credentials, error handling for timeouts, and ongoing certification work when the carrier changes its API |
| Manual or offline rate | B2B quotes, freight shipments or stores where staff confirm cost before dispatch | Staff time per order and slower checkout, so set a clear customer message for quoted orders |
| Single shipment per order | Orders that ship from one location with stock available together | Simplest packing and tracking, but one slow item can delay the whole order |
| Multiple shipments per order | Split stock across warehouses or ship items that cannot travel together | Each shipment needs its own rate, tracking number and customer notice, which raises fulfillment workload |
| Rates shown before address entry | Catalogs with one origin and a narrow set of destinations | Customers see a cost early, but estimates may change once the address is entered |
| Rates shown after address entry | Multi-zone or live-quote setups where cost depends on destination | Fewer surprises at payment, but an extra step that some shoppers abandon; test the flow with real addresses |
How a shipping build runs from rate design to go-live
This sequence turns carrier contracts and warehouse facts into a tested checkout that charges the right shipping amount for every order, with a documented handover to operations.
Confirm carriers, services and origin addresses
Your team and the implementation partner list every carrier account, service level and ship-from location that will be offered, including who holds each account and whether negotiated rates apply. Confirm which carriers have API access under your contracts and which need manual label creation. The output is a signed carrier and origin register that names the account owner for each carrier, the service codes to be exposed at checkout and the cut-off times that affect delivery promises. Work is complete when the business owner has approved the register in writing.
Model shipping profiles and product dimensions
Define the shipping profiles that group products by how they pack and ship, such as standard parcel, oversize, freight or digital (no shipping). Check that every purchasable product variation has weight, dimensions and a shipping profile, because missing values are the most common cause of wrong or failed rate requests. The product data owner fills the gaps from supplier specifications, and the partner writes a validation report listing products that cannot yet be quoted. Done means the report is empty or each exception has an agreed fallback.
Configure methods and rate rules
Create the shipping methods in Commerce Shipping, attach them to the stores and countries they serve, and set the rate rules: flat rates, rate tables by weight or zone, free-shipping thresholds and any surcharges. Decide how multiple shipments per order are split and which method applies to each shipment. The output is a rate matrix that finance and operations sign off, with one row per method, destination zone and rule, so every expected charge can be checked by hand before any carrier code runs.
Build or install carrier integrations
Decide whether each carrier is served by an existing contributed integration, a custom plugin or a manual rate table, and confirm that the chosen module supports the Drupal and PHP versions in use. Build custom code only where no maintained module fits, keep credentials in your secrets store and log every rate and label request. The output is a reviewed integration with a documented configuration for each carrier account, including how errors and timeouts fall back to a stored rate.
Set checkout display and fallback behavior
Configure how shipping options appear in the checkout pane: which methods show, their names and estimated delivery text, how the default option is chosen and what the shopper sees when no rate is available. Agree the messaging with the content owner and confirm that the displayed amount matches the order total after tax. The output is a checkout walkthrough recorded as screenshots for each store and destination type, approved by the business owner.
Test with sandbox accounts and edge cases
Run test orders against carrier sandbox or test accounts where the carrier provides them, and use manual test cases where they do not. Cover multi-item carts, split shipments, heavy or oversize items, PO boxes, international addresses, address corrections, tax-exempt buyers, zero-value orders and carrier outages. Record each test in a test order log with the input, expected rate, actual rate and result. Work is complete when every failed case is either fixed or has an approved workaround.
Go live and hand over a runbook
Switch the carrier accounts from test to production, place a small set of live orders, and compare the charged shipping amount with the signed rate matrix and the carrier invoice. Hand over a runbook that covers rate table updates, carrier credential rotation, adding a new service or origin, handling failed rate requests and checking carrier surcharge changes. The go-live is closed when operations has run one full order from checkout to label and the runbook has been accepted.
What drives shipping effort and how to keep it down
This table lists the main factors that expand shipping work on a Drupal Commerce store, with a way to reduce each one. Read it before scoping, since most of the effort comes from decisions made in the first week rather than from the code itself.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Number of carriers and services | Each carrier adds a rate integration, service level mapping, label or tracking handling and test cases across domestic and international lanes. | Launch with one or two carriers and a flat-rate fallback, then add carriers once order volume and checkout data justify them. |
| Live rate APIs and credential approvals | Live rates depend on carrier account credentials, sandbox access and sometimes approval steps that run outside the build schedule. | Request sandbox and production credentials at the start of scoping and confirm each carrier's approval lead time in writing before the build plan is fixed. |
| Product data quality | Missing or wrong weights, dimensions, package types and hazmat flags produce incorrect rates or blocked checkouts that are hard to trace. | Audit the catalog before the build, make these attributes required on product variations, and agree who owns updates after launch. |
| Hazardous and restricted goods flags | Hazmat classification changes which services are allowed and may require carrier-specific declarations or excluded shipping methods. | List restricted SKUs with the logistics team, map each to an allowed method set, and confirm the rules with each carrier before go-live. |
| Split shipments | Orders with items in different stock locations or with different handling needs can create multiple shipments, each with its own rate, label and tracking record. | Decide the consolidation rules early, such as one shipment per warehouse, and keep the shipment model simple unless the business case requires more. |
| Returns and return labels | Return rates, return label generation and refund rules depend on carrier services and sit outside basic checkout rate calculation. | Define the return policy and which carriers issue return labels before the build, and scope returns as a separate work item if they are not needed at launch. |
| International rules | Cross-border rates involve duties, tax treatment, restricted destinations, customs data and country-specific service availability. | Limit launch destinations to markets you can support, and confirm customs and duty responsibilities with the carrier and your tax advisor. |
| Custom rate logic | Bespoke rules such as free shipping thresholds, zone pricing, surcharges or negotiated rates add testing and maintenance for each rule. | Write each rule as a short specification with expected outputs, prefer carrier rates with a simple markup over custom formulas, and test each rule against sample orders. |
Carrier integrations: contributed modules or custom code
A contributed carrier module is the fastest route when a Drupal.org project already covers the carrier and account type you use. The module handles the rate request format, service levels and label fields, and your team mainly configures credentials, package defaults and which services appear at checkout. The trade-off is that you depend on a volunteer or small-team project, so its release history and open issues matter as much as its feature list.
What the team needs to supply and maintain:
- Carrier account: A production account with the carrier, with rate access enabled for your shipping profile and negotiated rates if you have them.
- API credentials: Keys or client secrets stored outside the codebase, with a rotation owner named in advance.
- Core compatibility: Confirm on Drupal.org that the module supports your current Drupal core and Commerce version before choosing it, since Drupal 11 and later releases can break older projects.
- Upgrade testing: Each Drupal or module update needs a staging test of live rate calls, not just a page load.
- Carrier API changes: Carriers retire endpoints on their own schedule, so budget for updates the module maintainers may not ship quickly.
Before you commit, check the module's last release date, its open security advisories and whether a maintainer still answers issues for your carrier.
A custom carrier plugin fits when no contributed module covers your carrier, your contract terms need special handling, or you must control every field sent to the carrier. The plugin implements the shipping method logic in your own code, so your developers own the request, response parsing, error handling and tests. This gives full control, but it also means the carrier integration becomes part of your application's maintenance burden.
What the team needs to supply and maintain:
- Carrier documentation access: Developer credentials, sandbox access and the current API specification from the carrier.
- Plugin design: A shipping method plugin with rate calculation, timeouts, caching of rate responses and graceful fallback when the carrier is slow.
- Test coverage: Automated tests against the carrier sandbox and recorded responses for regression checks after upgrades.
- Code review and ownership: A named maintainer who reviews changes to the plugin during each Drupal core update.
- Logging without data leaks: Logs that record errors and rate outcomes without storing full addresses or account numbers beyond your retention policy.
A custom plugin usually carries the highest long-term cost because every Drupal major version and carrier API change lands on your team. Ask any partner for a written plan covering who updates the code and how upgrades are tested.
A shipping aggregator or a manual rate table moves rate logic away from the carrier integration. An aggregator calls several carriers through one API, while manual rates use flat fees, weight bands or zone tables that your team maintains in Commerce configuration. Both reduce the number of carrier integrations you maintain, but they add a contract with a third party or a recurring task to update rates.
What the team needs to supply and maintain:
- Service contract: Pricing, data handling terms and supported carriers for an aggregator, reviewed with your procurement and privacy teams.
- Rate tables: For manual rates, a named owner who updates bands and zones when carrier tariffs change.
- Address and data flow: Documentation of which shipping fields leave your infrastructure, since an aggregator is an additional processor of customer data.
- Reconciliation: A monthly or periodic check of quoted rates against invoices from carriers, so margin errors surface early.
- Exit plan: How you would move to a direct carrier module if the aggregator changes price or drops a carrier you use.
Confirm with each aggregator which Drupal Commerce integration it supports, if any, before assuming a ready-made connector exists.
Whichever option you choose, the first check is compatibility between the module or plugin and your Drupal core version. Drupal 10 reaches end of life on December 9, 2026 and Drupal 12 is scheduled for the week of December 7, 2026, so a module that works today may need replacing within the life of your project. Checking compatibility on the project page before any build starts avoids paying for a rebuild.
What to verify on Drupal.org:
- Supported core versions: The core and Commerce versions listed on the module's project page and in its release notes.
- PHP requirements: Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later, so confirm your hosting runs a supported PHP version.
- Maintenance signals: Recent releases, open security issues and whether the maintainers respond to carrier API changes.
- Dependencies: Other contributed modules the carrier module requires, since each adds its own upgrade path.
- Carrier account requirements: Written confirmation from each carrier about the account type, API access and rate terms your contract allows.
Record these checks in the architecture decision so the choice can be revisited when Drupal core or the carrier changes.
Questions teams ask before building Drupal Commerce shipping
How much does a Drupal Commerce shipping build cost?
No single price applies, because cost follows the number of carriers, the rate logic and the number of warehouses or ship-from locations. Each carrier integration is a separate piece of work with its own account setup, testing and error handling. Rate logic such as flat rates by zone, weight bands, free-shipping thresholds or per-product handling adds design and testing time. Budget also covers checkout display, shipment labeling if you need it, and staging tests across order types. DeployOpen does not publish a price list. Ask for a written scope that lists each carrier, each rate rule, each warehouse and the test plan, then compare quotes against that same list. Ongoing carrier rate changes are a recurring cost that should appear in the support terms.
How long does shipping configuration take in a Drupal Commerce project?
Duration depends on the same drivers as cost: how many carriers you connect, how complex your rate rules are, and how quickly your team can supply accurate data and test accounts. A store with one flat-rate method and one warehouse moves much faster than a store that quotes live rates from several carriers across multiple ship-from locations. Carrier sandbox access and certification steps, where a carrier requires them, can set the pace more than development does. Ask for a timeline in the written scope that ties each milestone to the inputs you provide, so that delays in your data show up clearly.
What must our team provide before the build starts?
Gather these inputs before work begins, because most delays trace back to missing data:
- Carrier accounts, API credentials and sandbox access for each carrier you plan to quote or label with.
- Rate tables or service levels you have agreed with each carrier or your own logistics provider, including surcharges and minimums.
- Product dimensions and weights for every shippable variation, with a named owner who keeps them current.
- Warehouse and ship-from addresses, along with the stock locations each one serves.
- Your rules for free shipping, handling fees, excluded countries and delivery promises.
The partner should confirm each item in writing and state who is responsible for keeping it accurate after launch.
Can an internal Drupal developer build shipping alone?
A capable internal Drupal developer can configure flat-rate and zone-based shipping with Commerce Shipping, provided the rules are simple and the team has time to read the module documentation and test edge cases. Live carrier integrations are harder to own alone. They require handling carrier API versions, authentication, timeouts, rate caching, address validation, and error messages shown to customers at checkout. Ask whether your developer has built and tested a carrier integration before, and whether someone on the team can own the integration after launch. A partner can take the full build, the carrier work only, or a review of your internal build, and the written scope should say which.
Who maintains carrier rate changes after launch?
Carriers change rates, surcharges, fuel adjustments and service rules on their own schedules, so someone must own those updates after launch. Decide three things before go-live: who receives carrier notices, who updates rate tables or configuration, and who tests the change in staging before it reaches customers. Rate tables maintained by hand need a regular review cycle. Live carrier integrations need monitoring for failed rate requests, because a broken call can hide shipping options at checkout. Support retainers can cover these routines, and the quote should state what is included each month and what is billed as separate work.
What changes when Drupal core is upgraded?
Core upgrades affect your shipping setup through the modules it depends on, the PHP version, and any custom code that calls Commerce APIs. Contributed modules must support the new core version before you upgrade, so check their release notes and compatibility before you schedule the change. Plan a staging upgrade that runs shipping test orders across every carrier and rate rule. Drupal's core release schedule sets the timing of bugfix releases, security releases and major versions, and it also lists when each major version reaches end of life. Use it to plan your upgrade windows, and keep in mind that PHP version requirements can change with each major release.
Does the Drupal Commerce shipping module cost anything to license?
Drupal core and contributed modules hosted on Drupal.org are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself. The cost of shipping work is therefore labor, hosting, carrier fees and any paid services you choose, not a license fee for Drupal. Carriers may charge for API access, label stock or shipping services under their own contracts, and those terms should be confirmed directly with each carrier. Ask any partner to list third-party fees separately from its own professional services so that you can see the full cost of ownership.
How shipping connects to tax, stock and the rest of the store
Shipping rates do not stand alone in a Drupal Commerce order. The shipping amount feeds the order total, so it changes what the tax module calculates, what the payment gateway charges and what appears on the invoice. Tax is the connection most often underestimated. Confirm with your tax adviser whether shipping is taxable in each state or country you sell into, then check that the tax module treats the shipping adjustment as the rule requires. A rate that is correct on its own can still produce a wrong total once tax is applied on top of it. Confirm the order of adjustments in your build, since a different order can change the rounded amount.
Stock is the second connection. Shipping methods often depend on the warehouse or shipping origin chosen for an order, and that choice should follow the stock location that actually holds the items. If stock is split across locations, a rate quoted from one origin can promise delivery from a location that cannot fulfil the order. Test checkout with an out-of-stock item, a partial stock case and a multi-location case, and confirm which location the order's shipments are created against. The payment step is the third connection: a rate that changes after the customer has entered a card, or a shipment added after authorization, can cause a mismatch between the authorized amount and the captured total. Test that path with each gateway you run.
On the account side, the shipping profile is built from customer data held in the user account or a CRM. Address fields, saved shipping profiles and any contact data synced from an identity provider or CRM determine the address the rate calculation uses. Decide which system is the source of truth for a saved address, and test what happens when a profile is edited after an order is placed. Because the rest of the Drupal Commerce group covers tax, stock, payment gateways and CRM sync separately, this section only sets the test scope: run these connections together in a staging environment with real rate tables and the same gateway settings used in production.
What to hand over and what to keep in-house
This sequence ends with a handover package that lets your team operate shipping rates, labels and carrier connections after launch. It separates what DeployOpen delivers, what your staff must own, and what recurs once the site is live.
Export and version the shipping configuration
Export the Commerce Shipping configuration as code, including shipping methods, shipping rate plugins, package types, shipping services, order processors and the stores each method applies to. Store the export in the client's Git repository, with a reviewer named for changes. Done when a clean environment built from the repository reproduces the same shipping methods and rate calculations as staging, and the team has confirmed the diff is empty.
Hand over the rate matrices and name their owner
Document every flat rate, weight band, zone and free-shipping threshold in a rate matrix the business can read, and record which role owns each row (for example, operations for carrier rates, marketing for promotional thresholds). Name a single accountable owner and a backup for each matrix. Done when the owners have signed off the matrix against their current carrier contracts and the team can change one band in staging without developer help.
Store carrier credentials and set a rotation procedure
Move carrier account keys, API tokens and label credentials out of the site database and into your secrets manager or environment configuration, with access limited to named administrators. Write down who can issue new credentials, how an old key is revoked, and how the change is tested in staging before production. Done when the credentials are absent from exported configuration, the rotation steps have been performed once in staging, and the client holds the list of credential holders at the carrier.
Deliver the test cases and sandbox results
Provide a test script covering rate quotes at checkout for each shipping method, address and zone combinations, multi-package orders, label creation, tracking updates and refunds or voided labels, along with the results from the carrier sandbox runs. Record which tests use live carrier accounts and which use stubs. Done when every case has a recorded result, failures are logged with a fix or accepted risk, and the team can rerun the script without DeployOpen present.
Write the runbook for label and rate issues
Create a runbook that covers the common failures: no rates shown at checkout, a rate that differs from the carrier invoice, a failed label request, a duplicate or missing tracking number, and an order that splits into shipments unexpectedly. For each, state the first check, the log or admin page to read, who can act, and when to escalate to the carrier or to the implementation partner. Done when operations staff have walked through two scenarios in staging and the runbook is stored with the other operations documentation.
Agree the maintenance plan for carrier and Drupal changes
Define who monitors carrier API version changes and deprecation notices, who tests them in staging, and who approves production deployment. Include Drupal core and contributed module updates, such as the Drupal bugfix and security release cadence, and the process for re-running the test script after each update. Confirm in writing which work is covered by your internal team and which would be ordered as a separate retainer or change request. Done when the plan names owners for each item, the first test run is scheduled, and the fixed-scope agreement reflects who carries the recurring work.
Confirm the in-house ownership boundary
Hold a closing review that lists what the client team now owns (rate changes, credential rotation, daily label issues, carrier account administration) and what remains with DeployOpen under any agreed support arrangement (defect fixes within scope, module upgrades, new carrier integrations). Record the boundary in the handover document and have the named owners acknowledge it. Done when every handover item has an owner and an acknowledgement, and the team has confirmed which carrier contract terms and carrier-side account settings they need to verify independently.
How DeployOpen scopes and delivers Drupal Commerce shipping
DeployOpen plans, builds, documents and supports Drupal Commerce shipping rates and carriers inside your own infrastructure, using contributed modules from Drupal.org. Engagements start from a written scope, so the carrier list, rate logic and checkout behavior are agreed before any configuration begins.
How we scope
- Inventory the shipping methods, carriers, service levels and origin addresses your business needs.
- Document rate logic for flat, weight, price and carrier-quoted rates, with the rules you want to control.
- Agree in writing which carrier accounts, credentials and test environments the work depends on.
How we build
- Configure Commerce Shipping methods, shipping zones and rate calculation on a staging site first.
- Build carrier integrations and checkout rate display, with custom code kept in reviewable modules.
- Test rate accuracy, address edge cases and shipment splitting against the agreed scenarios before release.
How we hand over
- Deliver configuration exported to code, with a record of each module version and its Drupal compatibility.
- Document shipping rules, carrier credentials handling and steps for adding a new carrier or service level.
- Walk your team through checkout rate testing and the runbook for fixing rate errors after go-live.
How we support
- Support is available as a retainer covering module updates, carrier API changes and Drupal core upgrades.
- Review contributed module releases and security advisories that affect the shipping and carrier stack.
- Confirm with us during scoping which support hours, response paths and upgrade windows your team needs.

