Let’s assume your granny knitted 10 pairs of knitted socks. So you can’t sell 11 pairs. Learn how to manage your inventory.
You can find the source code of a full working example on Github:
Source Code
Let’s assume your granny knitted 10 pairs of knitted socks. So you can’t sell 11 pairs. Learn how to manage your inventory.
You can find the source code of a full working example on Github:
Source Code
Title: Knitted socks
----
Price: 14.99
----
Tax: 19
----
Stock: 10
Use hooks to throw exception if the stock is not sufficient.
Check the availability of the products with the initializePayment:before
and completePayment:before
hooks. For each item in the cart check if the available stock is smaller than the quantity of the cart item. If that’s the case an exception is thrown.
In this example we use Kirby’s helpful Exception
class to throw a nice error message.
<?php
use Kirby\Exception\Exception;
function checkStock($cart) {
foreach($cart as $cartItem) {
$cartItemPage = page($cartItem['id']);
$availableStock = $cartItemPage->stock()->toInt();
if ($availableStock < (int)$cartItem['quantity']) {
throw new Exception([
'httpCode' => 400,
'fallback' => '“{productTitle}” is out of stock',
'data' => [
'productTitle' => $cartItemPage->title(),
],
]);
}
}
}
return [
'hooks' => [
'ww.merx.initializePayment:before' => function ($data, $cart) {
checkStock($cart);
},
'ww.merx.completePayment:before' => function ($virtualOrderPage) {
checkStock($virtualOrderPage->cart());
},
],
];
It’s up to you were you print the exception / error message. For example you can use a checkout controller like this.
<?php
if (kirby()->request()->method() === 'POST') {
try {
$data = $_POST;
$redirect = merx()->initializePayment($data);
go($redirect);
} catch (Exception $ex) {
echo $ex->getMessage(); // e.g. “Knitted socks” is out of stock.
}
}
Merx comes with a default success template which prints the exceptions of the completePayment
method. You can/should use your own success template to handle completePayment
exceptions.
<?php
try {
$orderPage = merx()->completePayment($_GET);
go($orderPage->url());
} catch (Exception $ex) {
echo $ex->getMessage();
}
Use the completePayment:after
hook to update the stocks.
return [
'hooks' => [
…
'ww.merx.completePayment:after' => function ($orderPage) {
foreach($orderPage->cart() as $cartItem) {
$cartItemPage = page($cartItem['id']);
$newStock = $cartItemPage->stock()->toInt() - (int)$cartItem['quantity'];
$cartItemPage->update([
'stock' => (int)$newStock,
]);
}
},
],
];