在拉卡拉分账功能中实现实时更新,需结合异步回调通知和数据库事务来确保数据一致性。以下是具体实现方案
一、实时更新的核心逻辑
- 依赖拉卡拉分账回调
拉卡拉分账完成后会主动推送回调通知(类似支付回调),需监听该回调并更新订单分账状态。 - 数据库事务保障
分账金额更新、状态变更等操作需放在事务中,避免部分失败导致数据不一致。
二、代码实现
1. 分账回调处理接口
(监听拉卡拉分账结果推送,实时更新数据库)
// 文件:application/api/controller/Notify.php public function lakalaSharingNotify() { $data = file_get_contents('php://input'); // 获取拉卡拉分账回调数据 $lakalaApi = new \app\common\api\LakalaApi(); // 1. 验证签名(防止伪造请求) if (!$lakalaApi->verifySharingNotify($data)) { return 'fail'; // 验证失败直接返回 } $notifyData = json_decode($data, true); // 2. 开启事务 Db::startTrans(); try { // 3. 更新分账记录状态(示例字段) Db::name('profit_sharing') ->where('order_id', $notifyData['order_id']) ->update([ 'status' => 1, // 1=分账成功 'platform_amount'=> $notifyData['platform_share'], // 平台实际分账金额 'merchant_amount'=> $notifyData['merchant_share'], // 商户实际分账金额 'sharing_time' => time() // 分账完成时间 ]); // 4. 可选:更新订单状态(如标记为已分账) Db::name('orders') ->where('order_id', $notifyData['order_id']) ->update(['sharing_status' => 1]); Db::commit(); // 提交事务 return 'success'; // 必须返回success告知拉卡拉回调成功 } catch (\Exception $e) { Db::rollback(); // 回滚事务 \think\facade\Log::error('分账回调更新失败: '.$e->getMessage()); return 'fail'; } }
2. 主动查询分账状态(备用方案)
(若拉卡拉未提供回调,可定时任务轮询查询分账结果)
// 文件:application/command/SharingQuery.php (定时任务) public function handle() { $pendingOrders = Db::name('profit_sharing') ->where('status', 0) // 0=待分账 ->select(); foreach ($pendingOrders as $order) { $lakalaApi = new \app\common\api\LakalaApi(); $result = $lakalaApi->querySharingStatus($order['order_id']); if ($result['code'] == 'SUCCESS') { // 更新数据库(同回调逻辑) Db::name('profit_sharing')->where('order_id', $order['order_id'])->update([ 'status' => 1, 'platform_amount' => $result['platform_share'], 'merchant_amount' => $result['merchant_share'] ]); } } }
三、关键配置
1. 拉卡拉分账回调地址
在拉卡拉商户平台配置回调URL(需公网可访问):
https://yourdomain.com/api/notify/lakalaSharingNotify
2. 数据库表设计建议
需包含以下字段以支持实时更新:
CREATE TABLE `profit_sharing` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(50) NOT NULL COMMENT '订单ID', `platform_amount` decimal(10,2) DEFAULT '0.00' COMMENT '平台分账金额', `merchant_amount` decimal(10,2) DEFAULT '0.00' COMMENT '商户分账金额', `status` tinyint(1) DEFAULT '0' COMMENT '0=待分账,1=分账成功,2=分账失败', `sharing_time` int(11) DEFAULT NULL COMMENT '分账完成时间', PRIMARY KEY (`id`), UNIQUE KEY `order_id` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
四、注意事项
-
签名验证
回调接口必须验证拉卡拉签名(防止伪造请求),示例:// 文件:application/common/api/LakalaApi.php public function verifySharingNotify($data) { $sign = $data['sign']; // 拉卡拉提供的签名 unset($data['sign']); // 移除签名字段 ksort($data); $string = ''; foreach ($data as $k => $v) { $string .= $k . '=' . $v . '&'; } $string .= 'key=' . config('lakala.api_key'); return md5($string) === $sign; }
-
幂等性处理
回调可能重复推送,需确保重复请求不会导致多次更新:// 在更新前检查状态 if (Db::name('profit_sharing')->where('order_id', $notifyData['order_id'])->value('status') == 1) { return 'success'; // 已处理过则直接返回 }
-
超时处理
若拉卡拉分账长时间未回调,需通过定时任务主动查询(如每小时一次)。
五、前端实时展示(可选)
若需在前端实时显示分账状态,可通过以下方式:
- WebSocket推送:分账成功后主动通知前端。
- 轮询接口:前端定时调用 GET /api/order/sharing_status?order_id=xxx 查询状态。
通过以上方案,可确保分账结果实时更新到数据库,并与订单状态保持同步。实际开发中需严格遵循拉卡拉官方API文档的回调参数和签名规则。