iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

1
Modern Web

Laravel從入門到放棄…………原生PHP (疑?系列 第 46

[Day 45] Laravel實作 - 商品購買與交易記錄(四)

交易檢查及商品資料更新

除了使用驗證器驗證商品購買數量是否真的有購買數量(大於等於1的整數),我們還要確認在使用者購買這商品時,是否有足夠的數量可以販售給使用者,當數量不足以販售給使用者時,則要丟出例外訊息,終止這次的交易,避免出現商品超賣的狀況。

在實際的電子商務網站,會串接信用卡刷卡服務,或是其他的金流服務,確認真的能夠收到使用者付款的款項,當金流操作發生例外的狀況,一樣需要丟出例外訊息終止交易,在此次的範例為了簡化流程,沒有包含金流的處理,但在實際的電子商務網站應用中要把這些狀況考慮進去

//取得商品資料
$Merchandise = Merchandise::findOrFail($merchandise_id);

//購買數量
$buy_count = $input['buy_count'];
//購買後剩餘數量
$remain_count_after_buy = $Merchandise->remain_count - $buy_count;
if($remain_count_after_buy < 0)
{
    //購買後剩餘數量小於0,不足以賣給使用者
    throw new Exception('商品數量不足,無法購買');
}
//記錄購買後剩餘數量
$Merchandise->remain_count = $remain_count_after_buy;
$Merchandise->save();

當商品數量足夠販賣給使用者時,扣除這次使用者購物的商品數量,我們會更新商品剩餘可販售的數量到商品資料中,在Laravel中可以直接指定要更新的資料給Eloquent ORM Model物件,然後直接用->save(); 的方法就可以更新資料了,所以當我們異動商品剩餘數量到商品(Merchandise) Eloquent ORM Model後,就直接用$Merchandise->save(); 就完成商品資料更新的動作了。

交易例外處理

在交易發生例外錯誤時,我們會使用DB::rollBack(); 恢復原先交易資料,並沿用錯誤訊息模板元件,將使用者重新導向回原頁面,並顯示錯誤訊息

try
{
    //交易開始
    DB::beginTransaction();

    //...中間省略
    //交易結束
    DB::commit();

    //回傳購物成功訊息
    $message = [
        'msg' => [
            '購買成功',
        ],
    ];

    return redirect()
        ->to('/merchandise/'.$Merchandise->id)
        ->withErrors($message);
}
catch(Exception $exception)
{
    //恢復原先交易狀態
    DB::rollBack();
    
    //回傳錯誤訊息
    $error_message = [
        'msg' => [
            $exception->getMessage(),
        ],
    ];

    return redirect()
        ->back()
        ->withErrors($error_message)
        ->withInput();
}

記錄交易記錄

在做所有的電子商務或金流系統,務必要記錄每次交易當時的資料狀態及時間,這樣在事後交易發生問題時,才有資料可以追出發生的狀況,所以在購買商品後,需要記錄購買商品的資料,像是使用者編號(user)商品編號(merchandise_id)當時購買價格(price)購買數量(buy_count)交易總價格(total_price)交易建立時間(created_at),有這些資料,所以當交易成功後,會將這些的資料記錄到交易資料(Transaction)中

try
{
    //取得登入會員資料
    $user_id = session()->get('user_id');
    $User = User::findOrFail($user_id);

    //交易開始
    DB::beginTransaction();

    //取得商品資料
    $Merchandise = Merchandise::findOrFail($merchandise_id);

    //購買數量
    $buy_count = $input['buy_count'];

    //...中間省略...

    //總金額:總購買數量 * 商品價格
    $total_price = $buy_count * $Merchandise->price;

    $transaction_data = [
        'user_id' => $User->id,
        'merchandise_id' => $Merchandise->id,
        'price' => $Merchandise->price,
        'buy_count' => $buy_count,
        'total_price' => $total_price,
    ];

    //建立交易資料
    Transaction::create($transaction_data);
    //交易結束
    DB::commit();

    //...處理交易成功...
}
catch(Exception $exception)
{
    //恢復原先交易狀態
    DB::rollBack();
    
    //...處理錯誤交易...
}

當所有交易過程中需要檢查及異動的資料都完成後,就可以用DB::commit();結束這段交易,釋放原本被鎖定的資料,讓其他的使用者可以再次存取這些原本被鎖定的商品資料。

在交易完成確認後,為了簡化流程,先透過原先的錯誤訊息模板元件,將使用者重新導向原商品頁面,並顯示交易成功訊息。

$message = [
    'msg' => [
        '購買成功',
    ],
];

return redirect()
    ->to('/merchandise/'.$Merchandise->id)
    ->withErrors($message);

上一篇
[Day 44] Laravel實作 - 商品購買與交易記錄(三)
下一篇
[Day 46] Laravel實作 - 商品購買與交易記錄(五)
系列文
Laravel從入門到放棄…………原生PHP (疑?48

尚未有邦友留言

立即登入留言