Drupal Commerce 2

A Comprehensive Overview for Drupal Developers and Technical Managers

Contents
Introduction

Introduction

Commerce 2 is the latest version of the popular open source ecommerce platform for Drupal. Redesigned from the ground up with the experiences from more than 60,000 sites using the Drupal 7 version, Drupal Commerce 2 leverages the new architecture of Drupal 8 to provide robust core APIs, more features out of the box, and a vastly improved developer experience.

Built with customer experience as a first priority, Commerce 2 provides the core features needed by most e-commerce sites with minimal requirements on contributed modules or custom code, and the foundation for developing flexible omnichannel sales platforms, custom user experiences, and seamless third-party integrations.

In this article we will learn about the main systems and design patterns in Commerce 2, meet each of the core modules, and explore the online business opportunities made available by Drupal Commerce.

Special thanks to Steve Oliver for providing this technical overview.

Basics

Basics

Open source

Open source

Based on the free and open source content management framework Drupal, Drupal Commerce 2 is distributed under the GNU General Public License (GPL) which guarantees end users the freedom to run, study, share and modify the software. Companies that implement Drupal Commerce are not bound to any service provider, and retain complete control over their e-commerce codebase, free to innovate while they follow the collective progress of the project.

Developer experience and support

Developer experience and support

Commerce 2 has been developed from the start with a priority on helping other developers and agencies learn, use, and contribute to the project. Every day, nearly every hour of the day, there are code pull requests posted and reviewed on Github; discussion, support and planning on drupal.org; and ongoing threads of development and support topics on Slack.

See Docs > Developer guide > Developing

Semantic versioning and dependency management

Semantic versioning and dependency management

Like Drupal Core, Drupal Commerce follows semantic versioning and a fixed release schedule. Drupal Commerce 2.0 was released on September 20, 2017, and 2.1 on November 3. Releases will be the first Wednesday of each month. Like most well-managed php projects, dependencies are managed with Composer.

See Docs > Developer guide > Using Composer

Core concepts

Core concepts

From the project page:

Whereas eCommerce solutions are often developed with an application mindset, highlighting what you can do with it out of the box, Drupal Commerce was developed with a framework mindset, focusing on what you can build with it. The core Commerce systems make no hard-coded assumptions about your business model, privileging developers and site builders at the core level to build custom eCommerce solutions to suit.

See Docs > User guide > Key features

Entities

Entities

Many of the primary objects in Commerce are either configuration or content entities, which means they can be altered, swapped, and extended as needed. Entities regularly pass through the various system via events, while event subscribers from enabled modules manipulate the state of the entity and/or dispatch other events; Below is a complete list of all core entity types (as of Commerce 2.1):

Purchasable entities

Any entity that implements the PurchasableEntityInterface can be used by Commerce to represent a purchased entity in an order item. Commerce ships with one purchasable entity: the product variation. Other examples of purchasable entities are product bundles.

Entity forms and displays

Entity forms and displays

There are a few things regarding entity forms and displays:

  1. Drupal display and form modes are used to configure the appearance and behavior of products and variations in add to cart forms and order item displays.
  2. Many plugins provide or modify forms, e.g the checkout pane plugins provide child structures to the completed checkout form.
  3. Entity form classes are defined in PHP annotations and YAML services files and can be overridden in module alter hooks. (For example: the Cart module, if enabled, adds an ‘Add to cart’ form mode and sets the default form class for commerce order items.)
Plugins

Plugins

Several common plugins are YAML type plugins—things like log categories and templates, and checkout and order workflows. This simple text format makes it easy to implement custom customer experience and sales optimizations with a simple change to one file in your site’s configuration.

For things like checkout flows which have custom presentation and business logic with dependencies on other services, annotated PHP class plugins are used.

Plugin types

To implement your own functionality you can use, extend or replace these types of core plugins:

Core plugins

Drupal Commerce 2 ships with default plugins that provide some of the most common functionality required for modern sales and e-commerce platforms:

Custom plugins

Custom plugins can extend one of the base plugins to add promotion conditions or offers, for example, change the behavior of the add to cart form, provide custom panes in a checkout flow, or define a new order workflow.

Here are a few example contributed module plugins for Drupal Commerce 2:

Services

Services

Drupal 8 uses a dependency injection (DI) container to discover, access, and replace useful objects and their dependencies. In Commerce 2, some of the primary entry-points and core helpers for most of the functionality is provided by service collectors, event subscribers, order processors, resolvers, providers, managers, and cache context services. Work with these core services or use them as a reference when implementing custom functionality in Drupal Commerce:

Managers

Managers collect and instantiate different types of plugins, and services like the Cart manager and the Availability manager provide points of contact for custom and contributed code outside Drupal Commerce.

See Reference > Managers

Resolvers / service collectors

Resolvers are services ordered to form a chain of responsibility where modules can respond to situations they care about (or return nothing and pass the option along for a response from other modules). Drupal Commerce, usually via managers, determines things like unit price, tax rate, store, order type, and checkout flow using resolvers.

Custom or contributed code can implement resolvers to provide custom pricing, for example, or use a custom checkout flow for certain types of users.

See Reference > Resolvers

Event dispatchers

Event dispatchers are not a type of service, but these services are listed here to point out that they, in addition to other code, dispatch events. For example, the Cart manager creates, adds, updates, and removes order items, empties carts, and resets checkouts by dispatching events; the Order assignment service dispatches an event to assign anonymous orders to user accounts; the Order item matcher dispatches an event that finds matching order items and combines order items in the add to cart process.

There are several events that can be dispatched, and new events allow your code to trigger changes elsewhere in the system without needing to be concerned with the implementations of the event subscribers.

See Reference > Event dispatchers

Event subscribers

Event subscribers are PHP classes registered in services.yml files and ordered via a priority tag, that listen for different events broadcast from the system and take actions when appropriate. For example, the default Cart event subscriber displays a message when an entity is added to the cart, the Order number subscriber generates an order number when an order is placed, and the Order receipt subscriber sends an order receipt email when an order is placed.

See Reference > Event subscribers

Utilities

Various utility services exist to provide helpers and additional points of contact with Commerce. For example, the Cart provider creates, gets, and finalizes carts for an account; the Current store service holds a reference to the current store, resolved on demand; and the Promotion usage service tracks promotion usage.

See Reference > Utilities

Order processors

Order processors are services that make changes based on availability, promotions, or tax rules, for example, and are run during Order Refresh—the process used to modify an order periodically. The Availability order processor removes entities that are no longer available; The Promotion order processor applies promotions to orders; and the Tax order processor applies taxes to orders during the order refresh process.

See Reference > Order processors

Cache contexts

When creating renderables dependent upon commerce entities, cache contexts are available for country, cart, and store.

See Reference > Cache contexts

Order refresh

Order refresh

Order Refresh is a service that refreshes draft orders (such as carts) when they are saved and/or loaded. The Order entity’s storage handler calls the service’s ::refresh() method which runs all registered order processors (see Services above). The order refresh mode and frequency are configurable per Order type.

Workflows, states and transitions

Workflows, states and transitions

Workflows are YAML-based plugins that declare the available states and transitions for things like orders and payments. Workflows can be changed at run-time based on custom business rules, and states and state transitions can be evaluated and manipulated, e.g. to skip a step in a checkout flow or take action after transition events.

See commerce_order.workflows.yml, commerce_payment.workflows.yml

See Docs > Developer guide > State Machine

Events

Events

Events in Drupal 8 (largely replacing the hooks that existed in Drupal 7) are objects that are dispatched with a specific name at various times during the page and entity lifecycles, allowing other parts of the system opportunity to take actions or make changes to the object(s), decoupled from the code that dispatched the event.

Modules implement event subscriber services that listen for these named events and modify the passed objects or return specific responses to the dispatcher as needed. The event-dispatching code then considers the response(s) and/or modified event object.

See Reference > Events

Value objects

Value objects

Simple PHP classes that contain specific structured values for use throughout the system:

  • Adjustment - holds type, label, amount and other values to represent adjustments.
  • Context - holds customer, store and time values for “context” in various events.
Core modules

Core modules

Commerce modules are designed to be very loosely coupled, with few dependencies between core modules and dependable ways of responding to events and providing and altering plugins between modules. These 10 core modules provide the base functionality and example implementations for major e-commerce features and are all designed to be easily replaced and extended by contributed and custom modules.

Cart module

Cart module

The Cart module extends the order module by adding a ‘cart’ field to Order entities that allows orders to be considered “carts” and provides services for managing carts and cart items for users. It defines an Add to cart form display and sets the default plugin for Order item entities.

Dependencies: Order, Price, Product
Dependent modules: Checkout

See Reference > Events > Cart event objects

Checkout module

Checkout module

The Checkout module provides a default checkout implementation for orders, with a default checkout flow plugin that allows checkout panes to be grouped and ordered in sequential steps of a multi-step form. Modules provide custom functionality by defining checkout flows for each order type and providing custom checkout panes, form building plugins that attach their functionality to their configured position in the current checkout form.

Dependencies: Order, Cart
Dependent modules: (None)

See Docs > User guide > Checkout

Log module

Log module

The Log module provides activity logs for Commerce entities, implemented entirely in Twig and YAML. Modules can implement their own log categories and templates and generate log entries by passing the required context (variables) to any log template.

Dependencies: (None)
Dependent modules: (None)

Order module

Order module

The Order module defines the Order entity and associated features. Orders require order items, and order items require purchased entities. By default (in Commerce core) the only purchasable entity is the product variation. The order item type defines the order type and purchasable entity type it will support, and defines the configuration of the purchasable entity’s Add to cart form.

Dependencies: Price, Store
Dependent modules: Cart, Checkout, Payment, Promotion

  • Order item type = Purchasable entity type + Order type
  • Order item type defines purchasable entity’s Add to cart form display
  • Order item represents Purchased entity @ Unit price x Quantity
  • Order entities require Order item entities

See Reference > Events > Order event objects
See Docs > User guide > Orders
See Docs > Developer guide > Orders

Payment module

Payment module

The Payment module provides payment functionality to orders, with interfaces for specifying which features a payment gateway supports (e.g. authorizations, stored payment methods, refunds, etc.), and base classes for developing onsite and offsite payment gateway plugins.

Dependencies: Order
Dependent modules: (None)

  • Payment gateways are PHP plugins that supports onsite and offsite payment operations
  • Payment gateways are configured, with conditions (e.g store)
  • Payment methods (e.g. credit cards) can be stored locally/tokenized
  • Payments have fields for state/remote state, gateway and mode, amount/refunded amount and currency, and authorization and capture times.

See Reference > Events > Payment event objects
See Docs > User guide > Payments
See Docs > Developer guide > Payments > Available payment gateways

Price module

Price module

The Price module defines the Currency entity, a Price field, and associated features used in other Commerce modules. Currency entities are used by Stores to define which currencies they support, and Price fields are use for the base price of product variations and the unit price of Order items.

Dependencies: (None)
Dependent modules: Cart, Order, Product, Store

See Reference > Events > Price event objects
See Docs > Developer guide > Core components > Currencies

Product module

Product module

The Product module defines the product entities and associated features. Product entities represent one or more product variation entities in one or more stores. The Product module’s product variation entity is the default purchasable entity, and contains a SKU and price, plus any other fields configured for each product variation type. The product variation type defines the order item type that will represent the product variation in an order and the attributes that are available for those types of variations.

Dependencies: Price, Store
Dependent modules: Cart

  • Product variation type = Order item type + attributes
  • Product variation entities are the default purchasable entity
  • Product variations contain SKU, Price, and other configurable fields per variation type
  • Product entities require product variation entities

See Reference > Events > Product event objects
See Docs > User guide > Products
See Docs > Developer guide > Products

Promotion module

Promotion module

The Promotion module provides a UI for managing promotions. It runs a Promotion order processor that evaluates active promotion entities and any configured conditions, and applies fixed amount or percentage discounts to orders and order items during the Order refresh process. Promotions apply to stores and order types, and have an offer, start and end dates, usage limits, conditions, and compatibility settings with other promotions. Coupons can be used to limit access to promotions, and can be enabled/disabled and made available for a limited number of uses per coupon.

Dependencies: Order
Dependent modules: (None)

  • Promotion = Offer for Order type(s) at Store(s) with Condition(s) + Coupons
  • Promotions are [re-]applied during Order Refresh
  • Coupons can limit access to promotions

See Reference > Events > Promotion event objects
See Docs > User guide > Promotions

Store module

Store module

The Store module defines the Store entity and associated features. Stores can be used to represent different sales locations and/or different sellers in an online marketplace. Store content entities define the name, address, email, default currency, and supported billing countries for the store. Store type configuration entities define custom fields and entity modes for different types of stores. Order entities require exactly one store reference and product entities require one or more store references.

Dependencies: Price
Dependent modules: Order, Product

  • Stores represent different sales locations and/or sellers
  • Stores define the default currency to use
  • Stores define the supported billing countries
  • Orders and products require store(s)

See Reference > Events > Store event objects
See Docs > User guide > Setting up your store
See Docs > Developer guide > Stores

Tax module

Tax module

The tax module provides tax functionality to orders. It interacts with the order module by implementing an order processor that runs each order through applicable instances of configured Tax type plugins that apply tax type adjustments to the order or order items.

The core tax plugins work well for simple tax situations, but for situations requiring complex tax calculation and accounting, such as in the US, third party services such as Commerce Avatax now have modules for Drupal Commerce 2.

Dependencies: Order
Dependent modules: (None)

See Reference > Events > Tax event objects

Contributed modules

Contributed modules

While Commerce 2 provides most of the base functionality for e-commerce, and several of the contributed modules needed in Drupal 7/Commerce 1 are no longer required, contributed modules still provide advanced functionality on top of core Commerce modules for several different use cases.

Payments

Payments

There are several payment gateways available for Drupal Commerce 2. Here is a list of gateways with stable releases:

See Docs > Developer guide > Payments > Available payment gateways

Shipping

Shipping

The Commerce Shipping module has been developed as a contrib project for now. At some point it may be part of Commerce core, but for now, it is a stable module with a few popular shipping provider modules already released or being actively developed:

Recurring

Recurring

The Commerce Recurring module is being actively developed and nearly has a stable release.

Features:

  • Configurable billing intervals (charge every N days/weeks/months/years)
  • Fixed and rolling interval types (charge on the 1st of the month VS 1 month from the subscription date)
  • Prepaid and postpaid billing types (charge at the beginning or at the end of the billing period).
  • Prorating (adjusting the charged price based on the duration of its usage)
  • Configurable retries (for payment soft/hard declines)

Planned: Usage tracking, free trials.

Others

Others

  • Commerce Product Bundle - works for static bundles, needs work for dynamic
  • Commerce Stock - works, but API is not yet stable
  • Commerce Order Number - works, but a custom order number resolver service may work just as well, and simpler for some situations.
  • There are other modules, but there is no current comprehensive list. Ask in #commerce on drupal.slack.com for recommendations on specific solutions.
Summary

Summary

With this introduction to the fundamental concepts, main components, and core modules of Drupal Commerce 2, the reader should understand how entities, types, plugins, events and services provide the foundation for configuring, altering, and developing powerful custom ecommerce experiences.

Future articles will elaborate on individual features of Drupal Commerce and the contributed modules being developed for Commerce.

Reference

Reference

The main Commerce 2 events and services are listed here for convenience.

Events

Events

These are all the events passed at various times throughout the system.

Core event objects

Passed during events named in CommerceEvents:

Cart event objects

Passed during events named in CartEvents:

Order event objects

Passed during events named in OrderEvents:

Payment event objects

Passed during events named in PaymentEvents:

Price event objects

Passed during events named in PriceEvents:

Product event objects

Passed during events named in ProductEvents:

Promotion event objects

Passed during events named in PromotionEvents:

  • Coupon event - when creating, loading, updating or deleting a coupon.
  • Promotion event - when creating, loading, updating or deleting a promotion.

Store event objects

Passed during events named in StoreEvents:

  • Store event - when creating, loading, updating or deleting a store.

Tax event objects

Passed during events named in TaxEvents:

Services

Services

These are all the different types of services within the core Commerce modules.

Managers

See Core concepts > Services > Managers

Resolvers

See Core concepts > Services > Resolvers

Event dispatchers

See Core concepts > Services > Event dispatchers

Event subscribers

See Core concepts > Services > Event subscribers

Utilities

See Core concepts > Services > Utilities

Order processors

See Core concepts > Services > Order processors

Cache contexts

See Core concepts > Services > Cache contexts

Download and install Drupal Commerce 2

Download and install Drupal Commerce 2

Drupal Developer? Test drive the code using our install tool

Commerce Kickstart is the quickest way to get up and running with Drupal Commerce 2 and Drupal 8.

Visit Commerce Kickstart