wagnerwagner / merx Goto Github PK
View Code? Open in Web Editor NEWMerx is a plugin to create online shops with Kirby.
Home Page: https://merx.wagnerwagner.de
Merx is a plugin to create online shops with Kirby.
Home Page: https://merx.wagnerwagner.de
Hi,
looks like merx.wagnerwagner.de is down.
Hi I'm wondering if it's possible to disable online payments? I want customers to make an order online, but they have to pay in a shop. Can't find it in the documentation.
Thanks in advance!
Hello,
I have the following content structure:
content/
products/
1_598879/
product.el.txt
product.en.txt
product.el.txt:
Title: 598879
----
Price: 10.00
----
Tax: 24
...
If I log $productList, it is empty. Am I missing some requirement for pages to be listed as products?
Hi,
I have a problem with Checkout (on payment validation). Other people have a problem with the display of the basket.
Kirby 3.8.1.1
PHP 8
The tests were done in localhost and online.
https://forum.getkirby.com/t/merx-starterkit-e-commerce-cart-problem/25310/11
Hello,
it would be nice to add a new method to the cart object to get the total number of items based on quantity, eg.
// Cart contains two items A and B, A with quantity 1, B with quantity 3
cart()->count() // Returns 2, because 2 items
cart()->countQuantity() // Return 4, because 1 A and 3 B
One could use this method to display the total number of items in cart in the page header.
Might be better added to ProductList
rather than cart.
Cheerio
Is it possible to add iDeal support? After a lot of 'Gateway not supported' messages I discovered Merx has to support a payment method before it can redirect to Stripe, even if Stripe supports it already.
Kind regards,
Bart
For some reason we had two order pages with identical page numbers on our production server. This caused the changeNum hook to throw an exception, which caused heaps of chaos.
The order pages that caused the problem were named like this:
16_asfalsdkhfsgfk
16_fghksjfgslgfjsd
18_gslkgdjhalghf
One of the identical orders hat payment type prepayment, one paypal. I was wondering if this was a timing issue? Or if there is another reason why two orders could have been created with the same $page->num() when num should be incremental.
Hi there,
I was using the plugin in my installation and encountered issues when I wanted (for a clearer and user-friendlier structure) inside blueprints pages and templates folders to change the pages' names (for example, from checkout to shop-checkout), and in that way differentiate between my other page templates and the shop ones immediately (since unfortunately it is not possible in kirby to put them inside, let's say, a folder called 'shop', because kirby doesn't approve of structuring inside these blueprints/pages and template folders)
I realise that is is possible to adjust those in the plugin code itself, but on any next update I would have to care for that as well. Is there any option/idea/possibility to make these changeable, so that is more flexible?
Thank you!
I've noticed that Merx still uses the deprecated sources API for their SEPA Direct Debit payments. Which Stripe doesn't recommend using and businesses based in the European Economic Area (EEA) should follow the regulations and not use this outdated API.
Any way of upgrading?
Would it be possible to use a blueprint different than product.txt that would still be reccognized by MERX as a product?
Different products may have different panel form needs. In particular 'Shipping', as product, differs quite a lot to any other regular product, and would help to provide a specific blueprint for it.
As a workaround conditional fields may be used, and we can organize shipping products under a subpage, but still a workaround.
If this cannot be done, I believe it is a good feature to add.
Danke
In some rare cases, the sorting of the products can fail, due to the interference of other first level pages.
It would be nice, if the product pages could be moved into their own subfolder, instead of having them directly in the content root directory. For example if someone has set up a 'shop' page in the panel, all the product pages then go into this folder. Similar to the order pages.
Maybe having a option in the config.php
, like:
'ww.merx.productsPage' => 'shop',
I tried moving them manualy and by the blueprint setup. It worked for displaying them properly in the frontend and panel, but a function in the cart.php
of the plugin then doesn't seem to function anymore.
I've gone so far as making a structure as a field, show the options on the front-end and add the chosen size to the order. But when trying with multiple sizes. The Cart
object adds the different sizes together (while they should be separated) and thus merging the sizes and causing an issue. How do you separate the cart items?
I noticed that when an order is placed in a multilingual eshop, its text file (order.{lang}.txt)
is saved in the language the website was using during checkout . Is it possible to specify this language or just use the default language?
Hello,
I am getting the exception 'Item "{id}" could not be added to cart.'
when trying to add certain products to the cart.
Contrary to regular products, which I can add without problems, these products sit in a subpage
content
product A
product B
...
frame-options
frame-product A
frame-product B
These frame-products also have a different blueprint from regular products,frame-product.yml
which goes like this:
title: Frame Product
icon: box
options:
changeTitle: true
changeStatus: true
changeTemplate: false
changeSlug: true
delete: true
fields:
price:
label: Price
type: number
step: ,01
width: 1/4
placeholder: 0,00
after: €
width:
label: Width
type: number
width: 1/4
placeholder: 21
after: cm
height:
label: Height
type: number
width: 1/4
placeholder: 30
after: cm
passepartout:
label: Passepartout?
type: toggle
text:
- 'no'
- 'yes'
width: 1/4
default: 'no'
This is an example .txt file of such product:
Title: Wood, white
----
Price: 20
----
Width: 21
----
Height: 30
----
Passepartout: true
The code that triggers the exception is simply:
cart()->add([
'id' => 'wood-white'
]);
Which works fine by susbstituting the id by that of a regular product, such as 'cactus'
.
As I am not getting 'No "id" is provided.'
, 'Page not found.'
or 'Page must have a price field.'
I assume those are not the issues here (shouldn't be nevertheless).
So ¿what could be the issue?
Danke
Hi there, thanks for the incredible plugin. Is $cart->getSum()
meant to return the total price of all the products in the cart "including tax" as the documentation suggests? For me it excludes tax (with cart()->getTax()
returning a dollar amount, so it's not $0.00).
For example, 1 item in cart which costs $100, and is taxed at 10.25%. $cart->getTax()
returns $9.30* while $cart->getSum()
returns $100.00.
*this is something else I don't understand: the tax rate of 10.25% isn't getting applied correctly, and instead returns a number as if it was 9.3%. I see this happening in the "plainkit" example too.
I’ve noticed that ‘completed’ invoices are actually public kirby pages, correct ?
What do you reccomend in order to avoid anybody but the user accessing the order page?
As far as I can understand Babyreport example page seems to use robots.txt to hopefully avoid the orders master page to be crawled, and it also seems like the order master page is not http visitable, not sure by which method is this achieved on BabyReport.
But I assume that individual orders while virtually impossible to URL-guess, are still potentially visitable, and robots.txt could be potentially ignored by a crawler.
Is this correct?
Since invoices may contain very sensitive information are there any other safeguards in place or reccomendations on how to deal with invoice page security?
Danke
As explained in this forum post I have the need to specify product extras (such as topping for an ice-cream) which differ from variants in that the quantity of the extra may not match the quantity of the product. I may want 3 ice-creams but only 1 with topping. In this sense I cannot add the topping price to the product price, for it would be applied to all items of this product, not only those with the extra
This renders the product variant approach if not useless, at least cumbersome, for it seems I'd need to have a separate products for each combination of product + extra:
ice-cream
ice-cream + chocolate sprinkles
ice-cream + candy
It'd be useful to define an extra along its own quantity and price, and that such extra is included in the product's sum, perhaps something like:
cart()->add([
'id' => $id,
'quantity' => $quantity,
'extras' => // extra1, quantity, price / extra2, quantity, price ...
]);
Perhaps extras should be first defined as separate products then added to main product.
The key request here is that both $item['sum'] and cart->getSum() and even ->getTax(), etc all include the extras.
A workaround would be greatly appreciated.
Thank you
Hello,
I have this product in cart:
Array
(
[id] => cactus
[quantity] => 1
[title] => Cactus
[price] => 12.99
[taxRate] => 0
[tax] => 0
[sum] => 12.99
[sumTax] => 0
[frames] => Array
(
[0] => frames-options/wood-white
)
)
[frames] may contain one or several items, and I want to add or remove those.
Let's say I want to remove the single item actually present in [frames]
$product = 'cactus';
$frame = 'frames-options/wood-white';
/* Get frames array */
$frames = cart()->find($product)['frames'] ?? [];
/* Remove frame from array */
unset($frames[array_search($frame, $frames)]);
/* Build product */
/* Note that $frames is an empty array now */
$updatedProduct = [
'id' => $product,
'frames' => $frames,
];
/* Update product */
cart()->updateItem($updatedProduct);
I would expect this to update the product with an empty array but it does not seem to do so, this is the product on the cart after updating:
Array
(
[id] => cactus
[quantity] => 1
[title] => Cactus
[price] => 12.99
[taxRate] => 0
[tax] => 0
[sum] => 12.99
[sumTax] => 0
[frames] => Array
(
[0] => frames-options/wood-white
)
)
...exactly the same.
Something similar happens when updating the frames array with an array whose length is shorter:
Array
(
[id] => axe
[quantity] => 2
[frames] => Array
(
[0] => eine
[1] => zwei
)
...
)
cart()->update([[
'id' => 'axe',
'frames' => ['mango']
]]);
results in
Array
(
[id] => axe
[quantity] => 2
[frames] => Array
(
[0] => mango
[1] => vier
)
...
)
At first this was unexpected but after much testing it seems this is the expected behaviour of A::MERGE_OVERWRITE , which you @tobiasfabian probably use so the properties of a product that we are not providing in our updated product array are left untouched.
Unfortunately this translates to my nested array, and lefts me unable to remove items in this manner.
I need to think about how best to do this, but any ideas would be greatly appreciated
Thank you
Hello Merx team 👋
We recently moved to Kirby 3.7.1 and noticed an issue in the backend when accessing orders:
See Refactoring section here for more informations: https://github.com/getkirby/kirby/releases/tag/3.7.1.
After a purchase I noticed in the support phone number set in Stripe appears in the bank statement descriptor.
I tried adding the shortened descriptor in Stripe config, but nothing changes and the number is still there.
While reading this https://stripe.com/docs/statement-descriptors I was wondering that this probably can be achieved by adding it to here
Line 91 in 7a52a16
Hello,
I'd like to show each product sorting number in the 'items' structure field of order pages.
I can think of two ways:
Pass the number as a product property when adding it to the cart and add a 'number' field to the 'items' structure field in 'order' blueprint (will only work for future orders, not those already placed)
Add the number to a field in 'product' blueprint then add that field to 'ww.merx.cart.fields' - If I understood well, this would automatically add it to the product's array in the cart- then create the corresponding field in the 'items' structure field in 'order' blueprint (same problem).
Is there perhaps any better way of doing this in MERX ?
Danke
The formatPrice()
function doesn't seem to insert a thousands separator, even when locality is set to German.
Maybe it would be also be possible to have a config option, as with ww.merx.currencyPositionPrecedes
for example.
Something like:
'ww.merx.currencyThousandsSeparator' => '.'
Excerpt of the options currently set in my config.php
:
'locale' => 'de_DE.utf-8',
'ww.merx.currency' => 'EUR',
'ww.merx.currencySymbol' => '€',
'ww.merx.currencySeperateBySpace' => true,
'ww.merx.currencyPositionPrecedes' => false,
Hello, we are using PHP 7.4 and when we install merx 1.4.0 rc-1 via composer, it says that it is compatible only with stripe-php packages 6.28^ and not compatible with php-stripe 7. This is not a big problem, but there is a line in ApiRequestor.php (line 402) that uses array_key_exists('request-id', $rheaders)
and this does not work in php 7.4 as $rheaders is an object, so it is necessary to say (array)$rheaders
. This is fixed in stripe-php 7.
Will merx be compatible with stripe-php ^7.0 soon?
Hey after PHP Update i get this error.
Wagnerwagner\Merx\ProductList::__set(): Return type must be void when declared
PHP Version: 7.4.16
I have this error on every merx plugin installation.
I think there is some work todo for making merx plugin future proof.
Thanks for Fixing this as soon as possible.
Cheers Raphael
Hello merx team!
In order to keep dependencies as up to date as possible, it would be very nice if you could upgrade to the Paypal API v2.
Does this mean a lot of code refactoring on your side?
Thanks! 😉
Hi, and first of all nice plugin! :)
I’m moving a clients site to Kirby and Merx. The thing is that their site has more than 10 000 orders, and I’m wondering if it can be too much if I put all the orders under the same folder from a performance-perspective. The orders will of course only be for internal use so there will not be a lot of requests on that.
So my question is if you guys have any experience of sites with a lot of orders or any suggestion of what could be best way to handle this, like storing orders in db.
Thanks
I'm getting the following error after updating the sample Merx shop (starterkit) to Kirby 3.8.3 (same happens with 3.8.2) when calling up a product page. Running PHP 8.1.9.
Declaration of Wagnerwagner\Merx\ProductList::__set(string $key, $value) must be compatible with Kirby\Toolkit\Collection::__set(string $key, $value): void
{
"exception": "Kirby\\Exception\\Exception",
"message": "Pole bylo nesprávně zadáno.", //Field validation failed.
"key": "error.merx.fieldsvalidation",
"file": "site/plugins/merx/src/Merx.php",
"line": 233,
"details": {
"email": {
"label": "Email",
"message": {
"required": "Zadejte prosím jakoukoli hodnotu" //Please enter something
}
},
"phone": {
"label": "Phone",
"message": {
"required": "Zadejte prosím jakoukoli hodnotu" //Please enter something
}
},
"name": {...},
"street": {...},
"postalcode": {...},
"city": {...},
"countrycode": {...},
"paymentmethod": {...},
},
"code": 400
}
$page->blueprint()
language specificOrderPage->errors()
is run to check recieved form data, it runs inherited function from Kirby/Cms/ModelWithContent
(line 240) that is using said blueprint:/**
* Returns all content validation errors
*
* @return array
*/
public function errors(): array
{
$errors = [];
foreach ($this->blueprint()->sections() as $section) {
$errors = array_merge($errors, $section->errors());
}
return $errors;
}
OrderPage
is created without translations, just with "content" field, the validator sees data for validated blueprint as empty:{
...
"content": { // <- this should be validated
"deliveryMethod": "dpd",
"paymentMethod": "invoice",
"name": "John Doe",
"street": "Street 123",
"postalcode": "12345",
"city": "City",
"email": "[email protected]",
"countryCode": "CZ",
"useDifferentShippingAddress": "off",
"shippingaddressname": "",
"shippingaddressphone": "",
"shippingaddressstreet": "",
"shippingaddresspostalcode": "",
"shippingaddresscity": "",
"shippingAddressCountryCode": "CZ",
"additionalinfo": "",
"legal": "on",
"items": "..."
},
"translations": {
"cs": {
"code": "cs",
"content": [], // <- this is actually validated
"exists": false,
"slug": null
}
}
...
}
Lock kirby version to 3.6.3, works but it's just workaround.
Set fields in blueprint as not translatable with translate: false, this did not help.
Try to generate the translation in OrderPage model itself, right before the check. I tried to do it in __construct and errors() function, but I didn't find a way how to make it work. Maybe it's possible.
Modify Merx.php on line 216 to generate default translation when creating OrderPage, this works and it looks like it is using same logic as kirby bugfix that introduced this. I am not really confident if this is the correct and future-proof way, not to mention actual multilingual site with more languages.
// create virtual order page
$virtualOrderPage = new OrderPage([
'slug' => Str::random(16),
'template' => 'order',
'model' => 'order',
'content' => $data,
// modification start
'translations' => [
kirby()->languageCode() => [
'code' => kirby()->languageCode(),
'content' => $data
]
]
// modification end
]);
Hey,
in merx-plainkit\site\plugins\merx\src\productList.php line 82 (public function __set(string $key, $value): self) it says:
Wagnerwagner\Merx\ProductList::__set(): Return type must be void when declared.
Maybe because I'm on the latest php version? 8.1.4?
I have the following options set:
/* Decimal and thousands separator for MERX*/
'ww.merx.currencyDecimalPoint' => ',',
'ww.merx.currencyThousandsSeparator' => '.',
'ww.merx.currencyPositionPrecedes' => false,
/* Currency for MERX */
'ww.merx.currency' => 'EUR',
'ww.merx.currencySymbol' => '€',
But this does not seem to work, for example the following:
<?= formatPrice(15.23)?>
Returns 15.23 €
, and localeconv() returns:
Array
(
[decimal_point] => .
[thousands_sep] =>
[int_curr_symbol] =>
[currency_symbol] =>
[mon_decimal_point] =>
[mon_thousands_sep] =>
[positive_sign] =>
[negative_sign] =>
[int_frac_digits] => 127
[frac_digits] => 127
[p_cs_precedes] => 127
[p_sep_by_space] => 127
[n_cs_precedes] => 127
[n_sep_by_space] => 127
[p_sign_posn] => 127
[n_sign_posn] => 127
[grouping] => Array
(
)
[mon_grouping] => Array
(
)
)
If I set Kirby's locale instead to something like:
'locale' => [
LC_ALL => 'es_ES.utf8',
],
Then the output of <?= formatPrice(15.23)?>
is 15,23 €
, and localeconv() returns:
Array
(
[decimal_point] => ,
[thousands_sep] => .
[int_curr_symbol] => EUR
[currency_symbol] => €
[mon_decimal_point] => ,
[mon_thousands_sep] => .
[positive_sign] =>
[negative_sign] => -
[int_frac_digits] => 2
[frac_digits] => 2
[p_cs_precedes] => 0
[p_sep_by_space] => 1
[n_cs_precedes] => 0
[n_sep_by_space] => 1
[p_sign_posn] => 1
[n_sign_posn] => 1
[grouping] => Array
(
[0] => 3
[1] => 3
)
[mon_grouping] => Array
(
[0] => 3
[1] => 3
)
)
...so either I am not providing the options correctly or the options are not working ?
Thank you
this causes, all contents to be treated as part of title
https://merx.wagnerwagner.de/docs/getting-started/add-products
i though my install is broken, maybe this can put some people off, at this early stage of explore your software
also in blueprint sample, there is no field type description in kirby nativly, I get error, I suppose should be texarea, otherwise a custom field type by merx isnt working for me
hello,
is it possible to add the same product to the cart twice, but with different attributes, e.g. a jacket in size 48 and a jacket in size 50.
right now, the size of the first product just gets overwritten if i add the second product.
i am trying to avoid the necessity of subpages for all product variations and would rather like to use a structure field in the product blueprint since it makes it much more easier to update, especially for a large amount of products.
any help on this is appreciated!
thank you for the great work on this plugin!
I am trying to integrate Stripe payments with Merx.
I used the exact same code from the example at https://merx.wagnerwagner.de/cookbooks/checkout-with-stripe-s-payment-intents, but as soon as the initializePayment() function is called, the error "Allowed memory size of 134217728 bytes exhausted (tried to allocate 143360 bytes)", is returned. Am I missing something?
'pattern' => 'shop-api/submit',
'method' => 'POST',
'action' => function() {
try {
$data = [
'paymentMethod' => 'credit-card-sca',
'email' => '[email protected]',
'name' => 'Chuck Norris',
];
$paymentIntentId = kirby()->session()->get('paymentIntentId');
$data = array_merge($data, [
'stripePaymentIntentId' => $paymentIntentId,
]);
$redirect = merx()->initializePayment($data);
return [
'status' => 201,
'redirect' => url($redirect),
];
} catch (Kirby\Exception\Exception $ex) {
return $ex->toArray();
}
},
Hello,
According to my EU based client, he oly needs to charget VAT to EU customers, but no VAT to non-EU customers.
How can this be handled in merx?
Could I for example overwrite the tax on cart->add() as suggested in the product variations cookbook for price ?
Danke
I've deployed my project to production however when I try to make a purchase with stripe credit card I get an error:
No such payment_intent: 'pi_xxxxxxxxxxxxx'; a similar object exists in test mode, but a live mode key was used to make this request.
In my config file I have added the live keys, set production
to true
and added the Merx license.
I want to add custom cart methods like #41, would be great if Cart
class extendable.
Getting following error when you use calculated price on product models.
Page must have a price field.
https://github.com/wagnerwagner/merx/blob/master/src/Cart.php#L47
Can be use isNotEmpty()
method instead of exists()
} elseif (!$page->price()->isNotEmpty()) {
throw new \Exception('Page must have a price field.');
}
I usually set the locale as an array because the the German numeric comma breaks stuff (padding-bottom: 80,12565% - fun):
'locale' => [
LC_COLLATE => 'de_CH.utf-8',
LC_MONETARY => 'de_CH.utf-8',
LC_NUMERIC => 'en_US.utf-8',
LC_TIME => 'de_CH.utf-8',
LC_MESSAGES => 'de_CH.utf-8',
LC_CTYPE => 'de_CH.utf-8'
];
This however breaks
Line 41 in 43e9b8d
My workaround which you're free to include:
$str = option('locale');
if (is_array($str)){
$str = $str[1];
}
$locale = substr($str, 0, 5);
Though I'm also thinking: doesn't Kirby already set the locale even if its in single language mode?
The code snippet in the documentation, "Getting started / Setup / Options" repeats four times the same array key ww.merx.stripe.live.publishable_key
which I believe is not correct. IMHO, it should rather read
return [
'ww.merx.stripe.test.publishable_key' => 'pk_test_xxx…',
'ww.merx.stripe.test.secret_key' => 'sk_test_xxx…',
'ww.merx.stripe.live.publishable_key' => 'pk_live_xxx…',
'ww.merx.stripe.live.secret_key' => 'sk_live_xxx…',
'ww.merx.paypal.sandbox.clientID' => 'xxx…',
'ww.merx.paypal.sandbox.secret' => 'xxx…',
'ww.merx.paypal.live.clientID' => 'xxx…',
'ww.merx.paypal.live.secret' => 'xxx…',
];
Hi,
Is there a full palinkit with Stripe ?
This one is ok and easy with Paypal https://github.com/wagnerwagner/merx-examples/tree/plainkit
Hi, I was curious if support for PHP8 is considered. When I switch to PHP8, I get some errors, so I assume this is not yet the case. Kind regards, Bart
In Composer 2.0 I get:
Class Wagnerwagner\Merx\Cart located in ./site/plugins/merx/src/cart.php does not comply with psr-4 autoloading standard. Skipping.
Class Wagnerwagner\Merx\Gateways located in ./site/plugins/merx/src/gateways.php does not comply with psr-4 autoloading standard. Skipping.
Class Wagnerwagner\Merx\Merx located in ./site/plugins/merx/src/merx.php does not comply with psr-4 autoloading standard. Skipping.
Class Wagnerwagner\Merx\Payment located in ./site/plugins/merx/src/payment.php does not comply with psr-4 autoloading standard. Skipping.
Class Wagnerwagner\Merx\ProductList located in ./site/plugins/merx/src/productList.php does not comply with psr-4 autoloading standard. Skipping.
Here I found an upgrading guide https://getcomposer.org/upgrade/UPGRADE-2.0.md
Hi! Is possible to install Merx via Composer? Best
Hi there,
we develop a shop with Merx and when we initialize a cart, we get the following TypeError.
TypeError
Argument 2 passed to Kirby\Cms\App::trigger() must be of the type array, object given, called in C:\dev\project_root\site\plugins\merx\src\cart.php on line 22
This was introduced in #1; The kirby()->trigger()
method expects an array rather than an object. I guess the purpose was to pass $data
to allow for calculations based on the cart content? Otherwise, one could pass an array like ['cart' => $this]
This is due to the method signature change to kirby()->trigger()
in the latest Kirby 3.4.0 release.
I am happy to provide more information.
Cheers
Trying to delete an order (such as a test sandbox order) results in the error message "Sorting number of a complete order cannot be changed." on top of the delete confirmation popup.
Clicking Delete again results in 'the page cannot be found' error:
...but deletes the order page.
Then errors start to happen. ->
So, as this is within a try / catch clause, apparently merx()->completePayment($_GET);
fails.
BUT the order appears in the panel orders page, and its payment show as complete.
It fails, but it completes.
Thank you
Is there a way to have a discount on a product? I've fumbled around with the ww.merx.cart
& editing the price itself, but there doesn't seem a way to correctly apply the discount.
Hi! I was looking the code of Merx to set the symbol before the number, and I found that is related with localeconv(), but sometimes this is not desired. Maybe it will be better to configure this via config options.
Here a demo code, maybe explain better what I’m thinking.
public static function formatPrice(float $price): string
{
$localeFormatting = localeconv();
$precedes = option('ww.merx.currencySymbolBefore', true);
$string = '';
if ($precedes) {
$string .= option('ww.merx.currencySymbol', '€');
if (option('ww.merx.currencySpace')) {
$string .= ' '; // non breaking space
}
}
$string .= number_format($price, 2, $localeFormatting['decimal_point'] ?? '.', $localeFormatting['thousands_sep'] ?? ',');
if (!$precedes) {
if (option('ww.merx.currencySpace')) {
$string .= ' '; // non breaking space
}
$string .= option('ww.merx.currencySymbol', '€');
}
return $string;
}
It would be great if the frequently used fields were formatted:
$item['price']
$item['sum']
cart()->getTax()
cart()->getSum()
Would be great also:
$item['priceFormat']
$item['sumFormat']
cart()->getTaxFormat()
cart()->getSumFormat()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.