-
Notifications
You must be signed in to change notification settings - Fork 175
Description
What happened?
Description
I am developing a React application that uses JSON requests to call the Commerce action end points.
I have a custom line item rule being for a custom ticket purchasable that determines whether the maximum quantity of that purchasable against a third-party system.
/**
* Register validation rules for when adding Ticket purchasable to a line item.
*
* This event is called before a line item is created and also when an order is
* updated, marked as completed or about to be paid.
*/
Event::on(LineItem::class, Entry::EVENT_DEFINE_RULES, function(DefineRulesEvent $e) {
/** @var LineItem $lineItem */
$lineItem = $e->sender;
if (!$lineItem->getPurchasable()) {
return;
}
if ($lineItem->getPurchasable()::class !== Ticket::class) {
return;
}
$maxPurchasableTicketQuantity = $lineItem->getPurchasable()->getMaxQuantity();
$e->rules[] = ['qty', 'integer', 'min' => 1, 'max' => $maxPurchasableTicketQuantity];
});
Say I have 5 tickets in my cart when I arrive at my payment step. I then complete the payment form and submit it.
In the meantime (prior to submitting the payment form), it's possible that the maximum quantity of available tickets has now reduced to less than 5 (e.g. 1 max).
At some point in the PaymentsController::actionPay()
, the line item validation is executing and detecting the qty
is now invalid. This means the order now has errors. Consequently, this triggers the following response from actionPay()
to be returned:
{
"cart": {
...
},
"paymentFormErrors": [],
"modelName": "paymentForm",
"paymentForm": {
"nonce": "tokencc_bj_znzy56_27bbxm_b5sr7x_37d5js_9q2",
"storeInVault": false,
"firstName": null,
"lastName": null,
"number": "",
"month": null,
"year": null,
"cvv": null,
"token": null,
"expiry": null,
"threeDSecure": false,
"savePaymentSource": false
},
"errors": [],
"message": "Invalid payment or order. Please review."
}
The problem is that the errors for the order are not accessible in the response, so there's no easy way to indicate to the user what the actual error is.
Debugging the PHP code in actionPay()
shows that $order->getErrors()
returns this:
{ ["lineItems.0.qty"]=> array(1) { [0]=> string(30) "Qty must be no greater than 1." } }
I would have expected the order errors are returned in the actionPay()
response.
Craft CMS version
5.7.5
Craft Commerce version
5.3.12
PHP version
8.2
Operating system and version
No response
Database type and version
No response
Image driver and version
No response