Laravel集成支付网关时出现500内部服务器错误,求解决方案
我已经创建了/user/deposit/create视图用于选择支付网关,并且在控制器中添加了BpalController(核心方法为CollectFunds、GiveFunds,包含postJson函数)。测试时,选择支付方式、输入存款金额及描述后点击提交,页面跳转至/user/deposit/bpal/submit时出现500内部服务器错误,未触发用户手机端支付请求。以下是支付控制器源码,求指导解决:
class BpalController extends Controller { var $url = 'https://test.api.testintegrator.com'; var $api_key = 'testkeyhere'; var $secret = 'secretkeyhere'; public function CollectFunds($tranId, $amount, $phone, $name, $reason) { $endPoint = $this->url.'/collections/create'; $service_id = 2; if (Str::startsWith($phone, '25678') || Str::startsWith($phone, '25677') || Str::startsWith($phone, '25676')) { $service_id = 5; } if (Str::startsWith($phone, '25675') || Str::startsWith($phone, '25670') || Str::startsWith($phone, '25674')) { $service_id = 1; } $payload = [ 'request' => [ 'vendor_tran_ref' => $tranId, 'service_id' => $service_id, 'post_data' => [ ['key' => 'amount', 'value' => $amount], ['key' => 'telephone', 'value' => $phone], ['key' => 'name', 'value' => $name], ['key' => 'reason', 'value' => $reason] ] ] ]; return $this->postJson($endPoint, $payload, ''); } public function GiveFunds($tranId, $amount, $phone, $name, $reason) { $endPoint = $this->url.'/payments/create'; $service_id = 2; if (Str::startsWith($phone, '25678') || Str::startsWith($phone, '25677') || Str::startsWith($phone, '25676')) { $service_id = 5; } if (Str::startsWith($phone, '25675') || Str::startsWith($phone, '25670') || Str::startsWith($phone, '25674')) { $service_id = 1; } $payload = [ 'request' => [ 'vendor_tran_ref' => $tranId, 'service_id' => $service_id, 'post_data' => [ ['key' => 'amount', 'value' => $amount], ['key' => 'telephone', 'value' => $phone], ['key' => 'name', 'value' => $name], ['key' => 'reason', 'value' => $reason] ] ] ]; $private_key = hash_hmac('sha256', $this->api_key.$tranId, $this->secret); return $this->postJson($endPoint, $payload, $private_key); } function postJson($endPoint, $payload, $private_key) { //Initiate cURL. $ch = curl_init($endPoint); //Encode the array into JSON. $jsonDataEncoded = json_encode($payload); //Tell cURL that we want to send a POST request. curl_setopt($ch, CURLOPT_POST, 1); //Attach our encoded JSON string to the POST fields. curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded); //Set the content type to application/json curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'x-api-key: '.$this->api_key, 'x-private-key: '.$private_key, )); //return response instead of outputting curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); //close connection curl_close($ch); $result = json_decode($result); return $result->response_data; } }
排查与修复方向
- 捕获cURL请求错误:在
postJson方法的curl_exec后添加cURL错误检查,直接定位网络或连接问题:if(curl_errno($ch)){ throw new Exception('cURL错误: ' . curl_error($ch)); } - 处理JSON解析异常:当前代码直接访问
$result->response_data,如果API返回非JSON内容(比如500错误页面)会触发致命错误,添加判断:$originalResult = $result; $result = json_decode($result); if(is_null($result)){ Log::error('API返回非JSON内容: ' . $originalResult); throw new Exception('API响应解析失败'); } if(!isset($result->response_data)){ throw new Exception('API返回格式异常: ' . json_encode($result)); } return $result->response_data; - 验证私钥传递逻辑:
CollectFunds调用postJson时传了空字符串作为私钥,确认API是否允许该接口私钥为空,否则会导致鉴权失败。 - 检查service_id默认值:如果用户输入的手机号不匹配现有前缀,
service_id会保持默认的2,确认API是否接受这个默认值。 - 查看Laravel日志:直接查看
storage/logs/laravel.log里的错误栈,500错误的具体原因(比如未引入Str类、参数缺失等)都会在这里记录。 - 校验路由与参数:确认
/user/deposit/bpal/submit对应的方法是否正确调用了CollectFunds,且$tranId、$amount等参数格式合法(比如金额是否为数字)。
内容的提问来源于stack exchange,提问作者Shafiq Lutaaya
相关产品推荐
相关产品推荐

