Allow donation or 'pay what you want'
Closed this issue · 11 comments
Hello,
I'm wondering if there would be a way with merx to allow an option where the customer determines the price they want to pay for a particular product? We have one new upcoming product in our store which will be sold a little differently, on a sort of 'donation' system where the customer pays what they want to recieve a book which will be physically shipped. Looking for a per-product solution rather than site wide.
Thanks!
I think what you want to do is already possible with Merx. Usually you add a new product to the cart like this:
$cart->add([
'id' => 'new-shoes',
]);
The price of the cart item is generated from the product page (in this case, new-shoes). If you add the price directly to the add()
method, the price from the product page will be ignored. You can do something like this:
// get the value of the price input
$userPrice = floatval(get('price'));
if ($userPrice >= 5) {
$cart->add([
'id' => 'new-shoes',
'price' => $userPrice,
]);
} else {
// tell user that minimum price is $5
}
Thanks for your help @tobiasfabian - I'm using the merx starterkit so would the best way to do this be inside cart-post.php
? I tried overriding the price
in that function but that seemed to break it and now the item wont be added to the cart
It would be helpful if you could share the code you used inside the cart-post.php
file to override the price. Based on that, I can look into the problem you have.
Say if I do this in cart-post.php
<?php
return [
'pattern' => 'shop/cart',
'auth' => false,
'method' => 'POST',
'action' => function () {
$cart = cart();
$key = $this->requestBody('id');
$quantity = $this->requestBody('quantity', 1);
$price = 5;
// if item (id) is already in cart, add up quantities.
if ($cartItem = $cart->get($key)) {
$quantity = $cartItem['quantity'] + $quantity;
}
checkStock(page($key), $quantity);
$cart->add([
'id' => $key,
'quantity' => compact('quantity'),
'price' => $price
]);
return $this->cart();
},
];
I have an error message Unsupported operand types: int * array
Thanks @rhjp92 for giving additional details.
It would be good to know where exactly the error occurs - in which file, in which line.
If you have not yet activated the debug mode, you can activate it, then you will get a more detailed error message.
The error message Unsupported operand types: int * array
means that at some point an array should be multiplied by an integer, which is not possible.
Can you please double check the Request of this POST. Is quantity
a number or an array? If present, it has to be a number.
I think I’ve found your problem.
This is what you do in your code:
'quantity' => compact('quantity'),
The compact()
function creates an array.
You should pass the $quantity
variable directly.
To ensure that a float is passed, you can prepend (float)
to the variable.
$cart->add([
'id' => $key,
'quantity' => (float)$quantity,
'price' => (float)$price,
]);
Appreciate your help! From there on was fairly straightforward to implement a donation option on products. Thanks!
Hi both of you :)
I was really happy I stumbled upon your conversation, since I need exactly that function for a social project of mine. Could you maybe give me a hint how the template side looks like? I implemented the same code to the cart-post.php
(I'm using the starterkit as well), but whenever I call get('price')
on my <input type="number" name="price" id="price">
it returns 0 in the cart.
I tried different names for the variables and the input, I put everything in a form element, but somehow I didn't get it to work.
Any little hint would be super helpful to me, since time is kind of rare to finish this. 😱
Thank you already! 🙏
This is my current cart-post.php
return [
'pattern' => 'shop/cart',
'auth' => false,
'method' => 'POST',
'action' => function () {
$cart = cart();
$key = $this->requestBody('id');
$quantity = $this->requestBody('quantity', 1);
$userPrice = floatval(get('price'));
// if item (id) is already in cart, add up quantities.
if ($cartItem = $cart->get($key)) {
$quantity = $cartItem['quantity'] + $quantity;
}
checkStock(page($key), $quantity);
$cart->add([
'id' => $key,
'quantity' => (float)$quantity,
'price' => (float)$userPrice
]);
return $this->cart();
},
];