Description
Increment id's for sales orders are still assumed to be numeric, though there is no schema requirement in eav_entity_store for a prefix being an int
. In the cases where the prefix is alphnum (as the db schema defines a varchar(50)
) the isOrderIncrementIdUsed()
method, when casting to int
, will always evaluate as 0
. When the value is cast and returns 0
as the increment_id in the where clause, concurrent orders on high-traffic stores may choose identical increment ids, causing some payment gateways to error on authorize/capture.
The method for reference:
public function isOrderIncrementIdUsed($orderIncrementId)
{
$adapter = $this->_getReadAdapter();
$bind = array(':increment_id' => (int)$orderIncrementId);
$select = $adapter->select();
$select->from($this->getTable('sales_flat_order'), 'entity_id')
->where('increment_id = :increment_id');
$entity_id = $adapter->fetchOne($select, $bind);
if ($entity_id > 0) {
return true;
}
return false;
}
So, in essence this is what happens:
[1] boris> $varchar = 'M00000101';
→ string(9) "M00000101"
[2] boris> (int)$varchar;
→ int(0)
It would be desirable to either see the db schema change to enforce a numeric-only increment id or, rather, remove the cast to int
(which is my current workaround).
Source:
https://github.com/magento/magento2/blob/master/app/code/Magento/Sales/Model/Resource/Quote.php#L178