-
Notifications
You must be signed in to change notification settings - Fork 101
Open
Description
環境
- EC-CUBE バージョン: 2.13.0 以降
- 影響範囲: 複数商品種別を使用している環境
- 決済モジュールの決済画面で、注文確認画面から戻る際に
SC_Helper_Purchase::checkDbMyPendignOrder()に処理を任せている場合 PENDING_ORDER_CANCEL_FLAG=falseの環境
問題の概要
複数の商品種別がカートに入っている状態で決済画面(クレジットカード入力画面等)から「戻る」ボタンをクリックした際に、購入対象の商品種別のカートが空になってしまう不具合が発生します。
再現手順
- 2種類の商品種別(例:おなべとおなべレシピ)をカートに追加
- 購入フローを進めて決済画面(クレジットカード入力画面)に到達
- 決済画面で「戻る」ボタンをクリック
- 購入確認画面に戻る
期待される結果
- 購入対象の商品種別のカートは復元される
- 購入対象外の商品種別のカートは保持される
実際の結果
- 購入対象の商品種別のカートが空になってしまう
根本原因
data/class/helper/SC_Helper_Purchase.php の checkDbMyPendignOrder メソッドにおいて:
- 注文完了時:
completeOrder→cleanupSessionで特定の商品種別のカートのみ削除 - 戻る処理時:
getKeys()で全ての商品種別をチェック
この非対称な処理により、購入対象外の商品種別のカートが残存している場合、rollbackOrder ではなく cancelOrder が実行されてしまいます。
該当コード
// 1550行目
$cartKeys = $objCartSess->getKeys(); // 全商品種別をチェック
// 1555行目
if (SC_Utils_Ex::isBlank($cartKeys) && $target_time < $create_time) {
SC_Helper_Purchase_Ex::rollbackOrder($order_id, ORDER_CANCEL, true);
} else {
SC_Helper_Purchase_Ex::cancelOrder($order_id, ORDER_CANCEL, true); // こちらが実行される
}ec-cube2/data/class/helper/SC_Helper_Purchase.php
Lines 1555 to 1565 in ca2e30d
| if (SC_Utils_Ex::isBlank($cartKeys) && $target_time < $create_time) { | |
| SC_Helper_Purchase_Ex::rollbackOrder($order_id, ORDER_CANCEL, true); | |
| GC_Utils_Ex::gfPrintLog('order rollback.(my pending) order_id='.$order_id); | |
| } else { | |
| SC_Helper_Purchase_Ex::cancelOrder($order_id, ORDER_CANCEL, true); | |
| if ($target_time > $create_time) { | |
| GC_Utils_Ex::gfPrintLog('order cancel.(my pending and time expire) order_id='.$order_id); | |
| } else { | |
| GC_Utils_Ex::gfPrintLog('order cancel.(my pending and set cart) order_id='.$order_id); | |
| } | |
| } |
修正提案
注文詳細(dtb_order_detail → dtb_products_class)から購入対象の商品種別を取得し、その商品種別のカートのみをチェック対象とする:
// 注文詳細から商品種別を取得
$arrOrderDetails = static::getOrderDetail($order_id);
$orderProductTypes = array_unique(array_column($arrOrderDetails, 'product_type_id'));
// 購入対象の商品種別のカートのみチェック
$purchaseCartEmpty = true;
foreach ($orderProductTypes as $productTypeId) {
if ($objCartSess->getTotalQuantity($productTypeId) > 0) {
$purchaseCartEmpty = false;
break;
}
}
if ($purchaseCartEmpty && $target_time < $create_time) {
SC_Helper_Purchase_Ex::rollbackOrder($order_id, ORDER_CANCEL, true);
} else {
SC_Helper_Purchase_Ex::cancelOrder($order_id, ORDER_CANCEL, true);
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels