22

Obviously it's going to depend on each specific project, and I can only talk from my own (store owning) perspective, but over the years I have evaluated and installed and played with just about every ecommerce system of significance on the planet today. The ones I've spent most time with are BigCommerce (in it's self hosted form before it went SAAS), EE &...


12

Correct, you need to use fields[customFieldName] as the input name. The following form should do it: <form method="POST"> <input type="hidden" name="action" value="commerce/cart/updateCart"> <input type="text" name="fields[myCustomField]" value="Test123"> ... <input type="submit" value="Update Custom Field"> </...


11

You will need to write a plugin with three responsibilities: Keep track of which entries have been purchased Set an entry to enabled when it has been purchased Ensure that entries always have the correct status (enabled/disabled) whenever they are saved For the first one, you will need to create a new DB table that can store records of which entries have ...


9

Ignore the terminology, it really makes no sense. What it should say is this... Require customers to use a PayPal account? [Sole] No, a PayPal account is optional. Customers can still choose to pay with a credit card instead. [Mark] Yes, a PayPal account will be required to complete a purchase. Here's a screenshot of the documentation... So why did ...


8

To setup/debug email issues in commerce it's easiest to set up the simplest possible email and work your way up from there. Check your Craft email settings - can you send & receive the test email successfully? In Commerce settings, double check you have created your email correctly and that your template exists at the path you set. To simplify things ...


8

[** Updated Dec 2016] I think at this stage the best approach will be plugin based. Create a business logic plugin if you haven't already. Two good ways of doing that are : Business Logic Plugin or via https://pluginfactory.io If you listen to: https://craftcommerce.com/docs/events-reference#commerce_lineitems.onpopulatelineitem ...then you can do (...


8

Getting a flash message also deletes it, so you should set it to a variable first, otherwise, when you try to access it a second time, it will be empty. So you need to do something like this: {% set flashNotice = craft.session.getFlash('notice') %} {% if flashNotice %} <div data-alert class="alert-box info radius"> {{ flashNotice }} &...


8

Usually when selling goods that come in different size and colors, a different SKU would exist for any size/color combination that you sell, thus a unique variant. So, when that item becomes low in stock (Stock Keeping Unit), you can order more in. In Craft Commerce we do not automatically generate every combination of variant based on the custom fields ...


8

Thanks to @PhilipBoomy for his answer. The problem were missing cron jobs. Additionally I want to add one more solution from the craft support team: If you don't have the queue set up to run automatically with a cron job or worker, you can also try adding this to your order confirmation template: {# run queue #} {% do craft.app.queue.handleResponse %} {{ ...


7

The documentation for adjusters is here: https://craftcommerce.com/docs/adjusters and https://craftcommerce.com/docs/order-adjustment-model Essentially your plugin creates a class that fulfils the interface at: plugins/commerce/Commerce/Adjusters/Commerce_AdjusterInterface.php - which is very simple: interface Commerce_AdjusterInterface { /** * ...


7

Product types are really all about data concerns - so if the data you're storing for your canines/equines (hereafter known as dogs and horses to save some typing ;) ) - is the same, then you're right you don't need more than one product type. So let's say you make one type of product Animal. The most obvious tool for grouping that Craft provides is ...


7

You get the related transactions for an order with order.transactions So you can loop over the transactions like so: {% for transaction in order.transactions %} {{ transaction.type|title }} {{ transaction.status|title }} {{ transaction.amount|currency(transaction.currency) }} ({{ transaction.currency }}) {{ transaction.paymentMethod.name }} {{ ...


7

You won't be able to collect all information and take payment using one form/action. The customer information is added to the cart using commerce/cart/updateCart and payment is processed using commerce/payments/pay. To show the available shipping methods to a customer, Craft Commerce needs to know the shipping address to match against the rules you've set ...


7

Yes, you can do all the normal commerce actions via ajax. A basic recipe is this... HTML: <form method="POST" id="addToCartForm"> {{ getCsrfInput() }} <input type="hidden" name="action" value="commerce/cart/updateCart"> <input type="hidden" name="redirect" value="/cart"> <input type="hidden" ...


6

You could set a variable to access the products model like so: {% set product = item.purchasable.product %} and then access the fields like normal {{ product.myCustomField }} The snapshot holds the products fields as they were at the time the line item was added to the cart. So depending on how you're using the fields would dictate the method used. You ...


6

Answer is the example code for the cart: {{ item.options.giftWrapped }}


6

You can use hasFlash() instead, or pass false as a third argument, otherwise the flash message is discarded after the first time it is accessed. {% if craft.session.getFlash('notice', null, false) %} <div data-alert class="alert-box info radius"> {{ craft.session.getFlash('notice') }} <a href="#" class="close">&times;</a&...


6

In Craft3 you can do it like this: use Craft; use craft\base\Plugin; use craft\commerce\models\Address; use yii\base\Event; class Custom extends Plugin { public function init() { parent::init(); Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $event) { $address = $event->sender; ...


6

You can get the total quantity of items with: cart.totalQty Docs: https://craftcommerce.com/docs/order-model#totalqty


6

The error messages are returned to the template as flash messages. Handling those is documented here: https://craftcms.com/docs/templating/craft.session One thing to watch out for is that flash messages are only available once, and are by default 'consumed' when you retrieve them: {{ craft.session.getFlashes() }} ...some other template code here.... {{ ...


6

I agree with the basic underlying premise that showing full cost - i.e. with shipping - is essential on the cart index page for a modern checkout. Customers loathe what they see as a hidden surprise if they hit shipping costs later in the process and your completion rate plummets in my experience. Luke's answer is right about the root cause of the issue - ...


6

I managed do this with the following: {% set variants = craft.commerce.variants({ product: product, hasStock: true }) %} {% if variants|length <= 0 %} Sold out {% else %} Add to basket {% endif %} The hasStock criteria takes unlimitedStock into consideration. if (isset($criteria->hasStock) && $criteria->hasStock === true) { ...


6

Click on USD under Commerce->Settings->Payment Currencies and change the dropdown from USD to EUR. That will become Commerce's new base/primary currency. If you also want to support USD, you can add it as a second currency now and setup a conversion rate.


6

Listen for the onBeforeOrderComplete event and do something like this (replacing values to match your setup). craft()->on('commerce_orders.onBeforeOrderComplete', function($event){ $order = $event->params['order']; if ($order->paymentMethodId == 2) { $order->orderStatusId = 3; } });


6

See What is getContent() / the ContentModel, and how do I use it to get and set custom field values? So you needed to change the method used for setting content on an element. Also see In a plugin, how do I save an entry with a related entry So the relation fields always expect an array of ids, even if there is a single relation. Putting those together ...


6

Sorry to hear about your disappearing developer. Stack Exchange as a Q&A site usually isn't the best place to find a developer, unless you'd like to post to Stack Overflow Jobs (https://stackoverflow.com/jobs). For Craft specific developers, there are a couple of places you could look: https://craftcms.com/partners https://www.workwithcraft.com/ https:...


6

The snapshot is there so that the key details of an order are forever more available on the order record. Imagine living with Commerce for a long time - you will of course most likely add, change and/or remove products (or variations) as time goes by. You might simply disable ones you remove, or you might delete them. If Commerce did not have line item ...


5

You'll need to keep any action URLs as commerce/, as these point to controller actions inside the Commerce plugin, not templates in your store directory. So if you find: <input type="hidden" name="action" value="store/cart/updateCart"> That will need to be restored to: <input type="hidden" name="action" value="commerce/cart/updateCart">


5

I use ajax autosave to achieve this, and ajax update the cart in the background (for notes, but also pretty much everything else). I essentially use the recipe from: from https://github.com/geniuscarrier/autoSave/ In the callback function that is called after the autosave event, I post the to the update cart controller. The JSON object that comes back ...


5

Close! This should do it: {% set products = craft.commerce.products({ relatedTo: (category), order: 'defaultPrice', }) %} With the quotes it's a string. Without the quotes, Twig is expecting a variable you've defined called defaultPrice that doesn't exist.


Only top voted, non community-wiki answers of a minimum length are eligible