Midtrans支付集成报错:total_item字段不能为空,求排查
问题排查与修复方案
核心错误原因
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'total_item' cannot be null 表示创建Penjualan记录时,total_item字段被传入空值,而数据库该字段设置了非空约束。以下是具体排查和修复步骤:
1. 启用验证器拦截非法请求
你仅创建了验证器实例,但未触发校验逻辑,导致不符合规则的请求直接进入数据库操作环节。需添加验证失败后的拦截处理:
$validator = \Validator::make(request()->all(), [ 'id_penjualan' => 'required|string|max:255', 'id_member' => 'required|string|max:255', 'total_item' => 'required|numeric|min:1', // 修正规则:数量应为数值类型 'total_harga'=>'required|numeric|min:0.01', 'ppn' => 'required|numeric|min:1', 'diskon' => 'required|numeric|min:1', 'bayar' => 'required|numeric|min:1', 'diterima' => 'required|numeric|min:1', // 移除重复的int规则,numeric已覆盖整数校验 ]); // 新增验证失败处理 if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); }
2. 修正total_item的验证规则
原规则将total_item设为string,但该字段是商品数量,属于数值类型,改为required|numeric|min:1可避免因规则不匹配导致参数被过滤。
3. 检查前端参数传递
- 确认DataTables提交的表单/AJAX请求中,是否包含
total_item字段,字段名需与后端接收的total_item完全一致(注意大小写、下划线格式)。 - 若为AJAX提交,确保请求的
Content-Type为application/x-www-form-urlencoded或multipart/form-data,Laravel才能正确解析参数。
4. 修复事务内变量作用域问题
当前代码中$snapToken在闭包内定义,闭包外无法访问,会导致返回视图时出现Undefined variable: snapToken错误,需通过引用传递变量到闭包外:
$snapToken = null; \DB::transaction(function() use($request, &$snapToken) { // 用引用传递$snapToken $penjualan = Penjualan::create([ 'id_penjualan' => $request->id_penjualan, 'id_member' => $request->id_member, 'total_item' => $request->total_item, 'total_harga' => $request->total_harga, 'ppn' => $request->ppn, 'diskon' => $request->diskon, 'bayar' => $request->bayar, 'diterima' => $request->diterima, 'id_user' => auth()->user()->id ]); $params = array( 'transaction_details' => array( 'order_id' => rand(), 'gross_amount' => $penjualan->bayar, ), 'item_details' => array( [ 'id' => $penjualan->id_penjualan, 'price' => $penjualan->harga_jual, 'quantity' => $penjualan->jumlah, 'name' => $penjualan->nama_produk ] ), 'customer_details' => array( 'first_name' => $request->get('uname'), 'last_name' => '', 'email' => $request->get('email'), 'phone' => $request->get('number') ), ); $snapToken = \Midtrans\Snap::getSnapToken($params); $penjualan->snap_token = $snapToken; $penjualan->save(); $this->response['snap_token'] = $snapToken; }); return view('midtrans.payment', ['snap_token'=>$snapToken]);
5. 额外修复点
payment_post方法中最后使用了未定义的$order变量,需改为$penjualan:
return $penjualan->save() ? redirect(url('/'))->with('alert-success', 'Order berhasil dibuat') : redirect(url('/'))->with('alert-failed', 'Terjadi kesalahan');
内容的提问来源于stack exchange,提问作者dian_
相关产品推荐
相关产品推荐

