I'm experimenting with Commerce 2 and Drupal 8.

I want to set up a flow where people can pay for a node-- use cases like classified ad listing (pay per post), event signup (pay to register), and so on.

Here's what I did so far.

  • Create a content type classified ad.
  • Create a product 1 month of ad exposure.
  • Add an entity reference field on classified ad with the default value set to 1 month of ad exposure. Set the display widget for this field to rendered entity. Hide this field with field permissions. (This allows the user to create a classified ad node and then see an Add to cart button for the correct product after saving.)

So far, so good. But, with this configuration, the order doesn't have any information about the original node (content type: classified ad). I need to know which node the purchase/order was made for because I want to publish that node.

So, I changed the default order type: I added an entity reference to content of type classified ad. But how do I populate this entity reference field with the correct node? Or is there a better way to link the node for which the product was purchased with the order?


You need to create an order and an order item yourself and then add those values, I assume you need to do this from the context of your node anyway and not use a standard "buy this product" form.

A snippet from a project:

$order_item_values = [
  'type' => 'order_item_type',
  'title' => 'label',
  'unit_price' => new Price(...),
$order_item = $this->entityTypeManager()->getStorage('commerce_order_item')->create($order_item_values);

$order_type = $this->orderTypeResolver->resolve($order_item);

$stores = $this->entityTypeManager()->getStorage('commerce_store')->loadMultiple();
$store = reset($stores);

// Create the new order.
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $this->entityTypeManager()->getStorage('commerce_order')->create([
  'type' => $order_type,
  'store_id' => $store->id(),
  'uid' => $this->currentUser()->id(),
  'cart' => FALSE,


$this->cartSession->addCartId($order->id(), CartSessionInterface::COMPLETED);

return $this->redirect('commerce_checkout.form', ['commerce_order' => $order->id()]);

You don't even need to use products, you can define an order item that just has a price and reference to your node. But you can also use products to define e.g. the length/price.

  • Where does code like this snippet go? Sep 23 '17 at 11:06
  • 1
    That's entirely up to you, you can build a form or so that is displayed on the node or a local task or so.
    – Berdir
    Sep 23 '17 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.