Laravel 10:非成功支付API完整响应获取与入库问题
解决方案
1. 记录完整的非成功支付API响应
要解决日志截断问题,需手动获取并记录完整响应体,而非依赖框架默认输出:
// 接收第三方响应后,直接提取完整响应内容 $fullRawResponse = $response->getBody()->getContents(); // 将完整响应存入日志,用数组形式避免自动截断 Log::channel('logs')->info('Unsuccessful Payment Raw Response', ['raw_content' => $fullRawResponse]);
若日志仍截断,调整config/logging.php中对应通道的行长度限制:
'channels' => [ 'logs' => [ 'driver' => 'single', 'path' => storage_path('logs/payment.log'), 'level' => 'info', 'line_length' => 10000, // 增大单行日志长度上限 ], ],
2. 正确处理响应转义并对齐结构
原方法的stripslashes易破坏合法JSON结构,改用JSON原生解码逻辑处理转义,同时补全缺失字段对齐成功响应结构:
private function formatApiResponse($originalResponse) { // 尝试直接解码原始响应 $decoded = json_decode($originalResponse, true); // 解码失败则尝试处理双重转义场景 if (json_last_error() !== JSON_ERROR_NONE) { $unescapedResponse = stripslashes($originalResponse); $decoded = json_decode($unescapedResponse, true); if (json_last_error() !== JSON_ERROR_NONE) { Log::channel('logs')->error('Failed to decode API response', ['raw' => $originalResponse]); throw new \Exception('Invalid API response format'); } } // 补全缺失字段,与成功响应结构统一 return array_merge([ 'output_ConversationID' => 'N/A', 'output_TransactionID' => 'N/A', 'output_ThirdPartyReference' => 'N/A', ], $decoded); }
3. 标准化非成功响应入库逻辑
修改入库方法,直接使用格式化后的数组取值,避免硬编码默认值:
private function insertUnsuccessfulApiResponse($response, $formattedResponse, $id) { try { ApiResponsesMpesa::create([ 'status_code' => $response->getStatusCode(), 'output_ConversationID' => $formattedResponse['output_ConversationID'], 'output_TransactionID' => $formattedResponse['output_TransactionID'], 'output_ResponseDesc' => $formattedResponse['output_ResponseDesc'], 'output_ResponseCode' => $formattedResponse['output_ResponseCode'], 'output_ThirdPartyReference' => $formattedResponse['output_ThirdPartyReference'], 'transformed_request_id' => $id, ]); Log::channel('logs')->info('Unsuccessful transaction response saved to database'); } catch (\Exception $e) { Log::channel('logs')->error('Failed to save unsuccessful response', ['error' => $e->getMessage()]); throw $e; } }
完整调用示例
// 发起支付请求并接收响应 $response = Http::post($paymentGatewayUrl, $paymentPayload); // 处理响应 $fullRawResponse = $response->getBody()->getContents(); $formattedResponse = $this->formatApiResponse($fullRawResponse); // 判断支付状态并执行对应逻辑 if ($formattedResponse['output_ResponseCode'] === 'INS-0') { // 成功支付入库逻辑(保留原有实现) } else { $this->insertUnsuccessfulApiResponse($response, $formattedResponse, $requestId); }
内容的提问来源于stack exchange,提问作者Ivan Raposo
相关产品推荐
相关产品推荐

