Laravel使用Guzzle发起POST请求调用iPaymu接口失败如何解决
Laravel下Guzzle调用iPaymu沙箱接口异常排查
问题场景
项目开发中首次接触API调用,在Laravel框架下使用Guzzle HTTP客户端向iPaymu沙箱环境支付接口发起POST请求,参考资料编写的代码无法正常完成请求,但相同参数在Postman中测试可调用成功。
原有实现代码
$headers = [ 'Content-Type' => 'application/json', 'signature' => '73ceef837b9be3cf098eca4a4697bd6a36718b64b0cf407c4324415941ff9780', 'va' => '162789000', 'timestamp', '20191209155701' ]; $body = '{ "name": "Duty", "phone": "00028276", "email": "mm@gmail.com", "amount": "10000", "notifyUrl": "https://mywebsite.com", "expired": "24", "expiredType": "hours", "comments": "Catatan", "referenceId": "1", "paymentMethod": "qris", "paymentChannel": "qris" }'; $request = new Request('POST', 'https://sandbox.ipaymu.com/api/v2/payment/direct', $headers, $body);
Postman参考配置
参数与代码中书写的完全一致,参考截图:

代码存在的核心错误
- 请求头数组语法错误:
timestamp参数未按键值对格式书写,误写为两个独立数组元素,导致接口鉴权必需的timestamp请求头缺失,直接触发鉴权失败 - 未实际发起请求:仅实例化了
Request对象,未通过Guzzle客户端执行发送操作,代码不会产生任何网络请求 - 请求体构造方式易出错:手动拼接JSON字符串容易出现语法错误,且手动创建Request实例时未将字符串body转换为Guzzle要求的流格式,易出现传输异常
修正后的可运行代码
<?php // 引入Guzzle依赖类 use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; // 构造合法请求头,所有头信息均为键值对格式 $headers = [ 'signature' => '73ceef837b9be3cf098eca4a4697bd6a36718b64b0cf407c4324415941ff9780', 'va' => '162789000', 'timestamp' => '20191209155701' ]; // 用数组构造请求参数,避免手写JSON出错 $payload = [ "name" => "Duty", "phone" => "00028276", "email" => "mm@gmail.com", "amount" => "10000", "notifyUrl" => "https://mywebsite.com", "expired" => "24", "expiredType" => "hours", "comments" => "Catatan", "referenceId" => "1", "paymentMethod" => "qris", "paymentChannel" => "qris" ]; try { $client = new Client(); // 直接调用post方法发起请求,通过json选项传参会自动编码JSON、设置Content-Type头 $response = $client->post('https://sandbox.ipaymu.com/api/v2/payment/direct', [ 'headers' => $headers, 'json' => $payload, // 本地开发环境若遇SSL证书校验错误可临时开启,生产环境必须移除 'verify' => false ]); // 解析接口返回结果 $result = json_decode($response->getBody()->getContents(), true); dd($result); } catch (RequestException $e) { // 捕获异常输出错误信息,方便调试 $error = $e->hasResponse() ? $e->getResponse()->getBody()->getContents() : $e->getMessage(); dd($error); }
注意事项
- 代码中写死的
signature和timestamp仅适配当前测试参数,实际业务中必须按照iPaymu官方文档给出的签名规则动态生成,否则会出现鉴权失败 - 尽量避免手动拼接JSON字符串作为请求体,使用Guzzle提供的
json配置项传数组,由客户端自动完成编码,可减少大部分格式错误 - 若坚持手动实例化
Request对象,需要额外调用$client->send($request)方法才会实际发起网络请求
内容的提问来源于stack exchange,提问作者Fragmantedbin
相关产品推荐
相关产品推荐

