We are at the start of a larger project that will build on top of Drupal Commerce to build an online store that will serve two different markets. This has apparently not been done before with Drupal Commerce 2.0, but I could imagine it becoming a common use case, so I thought it would be good to have a public discussion on how to address such a use case.

Here are the overall requirements:

  • One single website, myinternationalstore.com
  • Multiple countries are supported (for example Germany and England), users pick their location when entering the site.
  • The same products are available everywhere, but the prices are country-specific (for example Product A costs 14€ in Germany and 12£ in the UK, no automatic conversion takes place).
  • VAT will need to be country-specific, but given that we'll rely on external data, this will most likely be a one-off solution.
  • While the checkout process will be the same, the payment gateway will at least have different configuration.

Here's how we plan to attack these requirements:

  • We created one store for each market.
  • We created a custom store resolver to match what the user selected when entering the site. We'll probably create a store selector with a path prefix, this might make a useful contrib module.
  • Regarding product prices, we can create one variant for each market. Exceptions are thrown for mismatching currencies, but we want to make sure that only variants for the current market are displayed. Alternatively, we could add additional fields to store the prices for each country and write a custom price resolver, but that would imply messing with the price fields, which I would like to avoid. This is really the one point where I'm unsure how to move forward, any idea on what solutions will get us the furthest?
  • Support for multiple/conditional payment options is not present yet, but we can easily extend the payment checkout pane to address that.

I will of course report on our findings. In the meantime I'm looking forward to hearing your feedback!

Comments

floretan created an issue. See original summary.

bojanz’s picture

Very happy to hear that you have a Commerce 2.x project!
Conditional payment gateway selection is on our todo lists for the upcoming weeks.
Let me know how much in a rush you are on that, and I can try to prioritize it.

This is definitely a use case that we'll want to document in the long run.
You have two options:
- Variation per store, then an event subscriber for the 'commerce_product.filter_variations' event that removes any variations that are not for the current store
- A price field per store on the same variations, then a price resolver that returns the right price for the current store

Which one you choose depends primarily on whether you consider the variations to be separate per store/country (with unique SKUs and optionally different info/images) or not. The price field approach is simpler, especially if you have only a few stores, the variation approach is more powerful.

floretan’s picture

Status: Active » Fixed

Thank you, that's exactly what I needed.

We will most likely go with the "Variation per store" option. These do have separate SKUs, and they get imported programatically anyway, so even if we end up having many variations per product it's not really an issue. The 'commerce_product.filter_variations' event was really the missing piece.

The conditional payment gateway selection would be nice to have, but it's not going to be needed in the coming weeks (we still have a payment module to write before that). From our side no need to change the prioritisation.

Alluuu’s picture

floretan: in my store I also would need a location variable (preferably in url, like language), but not only for what products to display but for other options as well. How did you go about creating the country selection and is it accessible everywhere? ideally I'd like all content to be publishable to specific locations, like it is for languages or user roles.

floretan’s picture

Here are the concrete steps we did. This is still not 100% final, but we'll probably publish a contrib module once we have ironed out the last issues.

  • Create a custom PathProcessor (implements InboundPathProcessorInterface and OutboundPathProcessorInterface like the language module) to add a path prefix to the path.
  • Create a custom store resolver that compares the path to store. If nothing is found, we create and return an "invalid store". This means we never reach the default store resolver.
  • Create an event subscriber listening to KernelEvents::RESPONSE which redirects the user to a store selection page if no valid store context is found.
  • Create an event subscriber listening to ProductEvents::FILTER_VARIATIONS (pointed out above), which filters out product variation based on the current store context.

The main issue we still have is that the product variation filter event is only called to determine what gets added to the cart, not what gets displayed (see #2834845: Product variation fields not affected by FILTER_VARIATIONS events).

bojanz’s picture

Status: Fixed » Active

Thank you for documenting this. Reopening the issue to make sure this gets moved to a documentation page.

I haven't had time to look at your bug yet (combination of offsite payments and shipping), but will try to do so soon.

13jupiters’s picture

Thanks @floretan - and for others who arrive here looking for this key functionality, it appears that floretan has since posted https://www.drupal.org/project/commerce_country_store as the result of this research/work.

Since the dev release, there's been a change in commerce that affects commerce_country_store. https://www.drupal.org/node/2901315
(commerce_store\storeContext has been renamed commerce_store\CurrentStore). Working on issue/patch.

johnpicozzi’s picture

@bojanz - Any update on this? We have a similar set of requirements and our project team doesn't want to enter a variation per country (store)

Here are the overall requirements:

  • One single website
  • Multiple countries are supported (for example Germany and England), users pick their location when entering the site.
  • The same products are available everywhere, but the prices are store country-specific (for example Product A costs 14€ in German Store and 12£ in the UK Store, no automatic conversion takes place).
  • We are calculating tax using Avalara
  • While the checkout process will be the same, we will have different payment options per store

I see the module mentioned above, however that doesn't seem to do what we want. It almost seems like this could be solved with a "price table" that let you set price and currency per variation per store. Example - One variation would have a price for USD, a price for CAD, and a price for EUR.

Hope this makes sense and thanks for the great work on Commerce 2.x

bojanz’s picture

@johnpicozzi
Your hunch is correct, if you don't want a variation per store you'll want Commerce Pricelist.
I don't think it can do per-store prices yet, it's still in its early days, but we're planning to give it some time soon.

johnpicozzi’s picture

@Bojanz After some more digging into Pricelist I'm not sure it's solving the issue. I'm thinking this might be the way to go.

A price field per store on the same variations, then a price resolver that returns the right price for the current store

I have added individual fields for each currency to a product variation and disabled the default price field. We will code the resolver into a custom module to tie the stores default currency to one of the fields on the variation and set that to be the new price. The question I have is do you see any risk in doing this around integration with other contrib modules? Thanks!

Katharine_Gates’s picture

Slight different use case here:
Client wants one website, but each product has 3 fixed prices, i.e. $10, £8, €6 for the same product (flat prices - no currency conversion).

We want customers in USA and Canada to pay in $, People in Europe to pay in € and people in UK and elsewhere to pay in £.
In addition we have 5 shipping zones with fixed prices per product.

In Drupal 7 this was accomplished in Ubercart with a bunch of customization: Each product had 3 price fields (one in each currency) and 5 flat shipping rates (in their currency) modules.

All three prices show in displays throughout the site, but at checkout once customer provided country it automatically switched, showing only the currency/prices they are supposed to pay. The country also determined which fixed shipping rate they would pay per piece.

Anyone have any ideas for implementation in Commerce/D8?

johnpicozzi’s picture

Update: We started using the Commerce Price List module as @bojanz suggested. It works great and allows for each country to have it's own set of prices for a single product in the store. I would recommend going down that road for needed price differences. It links pricelist item to product and variation via SKU, so it's easy to configure and update.

We have added the following patches for some additional functionality.

https://www.drupal.org/files/issues/2019-04-02/commerce_pricelist-show-s...
https://www.drupal.org/files/issues/2019-05-08/3050543-11.patch

Hope this help!

bojanz’s picture

Status: Active » Fixed

Time to close this issue. The pricelist module is now very mature (and provides a "Prices" tab on the variation in addition to the usual global pricelist UI). We will be tagging an RC1 once Commerce 2.16 is out.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

nofue’s picture

As I'm trying to get this Commerce Pricelist module working for stores with different currencies, I'm still stuck even after reading all the way through this thread + examples.

The situation is the same as in the original post: one store, two currencies, selected by the TLD of the current user.

Issues begin with this line of the documentation:

Make sure to set the price field display settings to "Display the calculated sell price for the current user

I can't find any such price field settings anywhere in my D8 Commerce installation. Price field doesn't offer any choices, so where to start?

The "final notice" from bojanz

and provides a "Prices" tab on the variation in addition to the usual global pricelist UI

is even more confusing: Where/how am I expected to see that "prices" tab?

johnpicozzi’s picture

@nofue - I had to look this stuff up myself.

So the price field is under the display for your Variation Types (admin/commerce/config/product-variation-types/VARIATION_NAME/edit/display).

As for the prices list that should be on the edit screen for the variation itself. Not the product.

Feel free to hit me up in Drupal Slack if you need more help.

nofue’s picture

Thanks, John -- great starting point to dig further …