You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel如何在保存模型前获取ID,仅支付成功时保存记录?

解决方案

要实现「仅支付成功时才保存交易到数据库」的需求,有两种可靠的实现方式:

方法一:预生成交易ID(推荐)

先获取数据库中transactions表的下一个自增ID,用它生成支付网关需要的交易标识,待支付成功后再创建交易记录,从根源避免无效数据入库。

代码示例:

public function makeDeposit($amount, Pool $pool, $payment_method_id, $payment_number, $user_id)
{
    if ($payment_method_id === 1) {
        // 获取transactions表的下一个自增ID
        $nextId = DB::select("SHOW TABLE STATUS LIKE 'transactions'")[0]->Auto_increment;
        $transactionRef = "XMZDEP" . $nextId;

        // 调用自定义支付网关
        $result = $this->depositWithCustomGateway($transactionRef, $payment_number, $amount, $transactionRef);

        if ($result->status == 200 || $result->status == 201) {
            // 支付成功,正式创建交易记录
            $deposit = Transaction::create([
                'pool_id' => $pool->id,
                'user_id' => $user_id,
                'amount' => $amount,
                'payment_method_id' => $payment_method_id,
                'transaction_type' => 'deposit',
                'reference' => $transactionRef // 可选:存储网关交易标识
            ]);
            return $deposit;
        } else {
            throw new TransactionException($result->response->output_ResponseCode . " - " . $result->response->output_ResponseDesc, $result->status);
        }
    }
}

方法二:利用数据库事务回滚

先创建交易记录,通过数据库事务包裹操作,支付失败时触发回滚,删除已创建的无效交易。

代码示例:

public function makeDeposit($amount, Pool $pool, $payment_method_id, $payment_number, $user_id)
{
    if ($payment_method_id === 1) {
        return DB::transaction(function () use ($amount, $pool, $payment_number, $user_id) {
            // 临时创建交易记录(事务未提交,不会持久化)
            $deposit = Transaction::create([
                'pool_id' => $pool->id,
                'user_id' => $user_id,
                'amount' => $amount,
                'payment_method_id' => 1,
                'transaction_type' => 'deposit',
            ]);

            $transactionRef = "XMZDEP" . $deposit->id;
            $result = $this->depositWithCustomGateway($transactionRef, $payment_number, $amount, $transactionRef);

            if ($result->status != 200 && $result->status != 201) {
                // 支付失败,抛出异常触发事务回滚
                throw new TransactionException($result->response->output_ResponseCode . " - " . $result->response->output_ResponseDesc, $result->status);
            }

            // 支付成功,事务自动提交,交易记录持久化
            return $deposit;
        });
    }
}

两种方法对比

  • 预生成ID:无多余数据库写入操作,性能更优,适合高并发场景;
  • 事务回滚:逻辑更直观,依赖数据库事务机制保障数据一致性,但会产生「写入-回滚」的额外开销。

内容的提问来源于stack exchange,提问作者Muhammad Puspaceno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:15:36