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

PHP调用API时凭证无效求助(Postman可正常请求)

GSTZen EWB API调用凭证无效问题排查(Postman正常但PHP报错)

问题描述

通过PHP代码POST调用GSTZen的EWB API时,返回「请求中提供的用户凭证无效」,但使用相同凭证在Postman中可成功生成电子运单(EWB)。


凭证获取代码

<?php
session_start();
error_reporting(E_ALL); // 开启所有错误用于调试

// 数据库连接(示例使用PDO)

// 从apiusers表获取API用户名和密码
try {
    $sql = 'SELECT username, password FROM apiusers WHERE BPD_ID = :BPD_ID';
    $stmt = $pdo->prepare($sql);
    $stmt->bindParam(':BPD_ID', $BPD_ID);
    $stmt->execute();
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    $apiUsername = $user['username'];
    $apiPassword = $user['password'];
    
    // 在控制台输出用户名和密码
    echo "<script>console.log('Username: " . addslashes($apiUsername) . "');</script>";
    echo "<script>console.log('Password: " . addslashes($apiPassword) . "');</script>";
    
} catch (Exception $e) {
    die('获取API用户数据失败: ' . $e->getMessage());
}

请求数据构建

// 构建postData数组
$postData = json_encode([
    "supplyType" => "O",
    "subSupplyType" => "8",
    "subSupplyDesc" => "DC",
    .........
    "vehicleType" => "R",
    "itemList" => $itemData
]);

// 在页面输出请求数据
echo "<pre>";
print_r($postData);
echo "</pre>";

echo "<pre>";
print_r($itemData);
echo "</pre>";

完整请求JSON

{
    "supplyType": "O",
    "subSupplyType": "8",
    "subSupplyDesc": "DELIVERY CHALLAN",
    "docType": "CHL",
    "docNo": "DC242501",
    "docDate": "01/08/2024",
    "fromGstin": "29AAFCC9980M1ZR",
    "fromTrdName": "welton",
    "fromAddr1": "2ND CROSS NO 59  19  A",
    "fromAddr2": "GROUND FLOOR OSBORNE ROAD",
    "fromPlace": "FRAZER TOWN",
    "fromPincode": 560090,
    "actFromStateCode": 29,
    "fromStateCode": 29,
    "toGstin": "29AEKPV7203E1Z9",
    "toTrdName": "sthuthya",
    "toAddr1": "Shree Nilaya",
    "toAddr2": "Dasarahosahalli",
    "toPlace": "Beml Nagar",
    "toPincode": 560090,
    "actToStateCode": 29,
    "toStateCode": 29,
    "transactionType": 1,
    "otherValue": "0",
    "totalValue": 40000,
    "cgstValue": 0,
    "sgstValue": 0,
    "igstValue": 0,
    "cessValue": 0,
    "cessNonAdvolValue": 0,
    "totInvValue": 47200,
    "transporterId": "",
    "transporterName": "",
    "transDocNo": "",
    "transMode": "1",
    "transDistance": "100",
    "transDocDate": "",
    "vehicleNo": "PVC1234",
    "vehicleType": "R",
    "itemList": [
        {
            "productName": "MS & SCRAP",
            "productDesc": "SCRAP",
            "hsnCode": 7402,
            "quantity": 4,
            "qtyUnit": "BOX",
            "cgstRate": 9,
            "sgstRate": 9,
            "igstRate": 0,
            "cessRate": 0,
            "cessNonadvol": 0,
            "taxableAmount": 40000
        }
    ]
}

cURL请求代码

$url = 'https://my.gstzen.in/~gstzen/a/ewbapi/generate/?username=' . rawurlencode($apiUsername) . '&password=' . rawurlencode($apiPassword);
$apiKey = 'de3a3a01-273a-4a81-8b75-13fe37f14d';
$gstin = '29AAFCC9980M1'; // GSTIN值
/* $gstin = $mainData['COMP_GSTIN']; // GSTIN值 */

// 初始化cURL会话
$ch = curl_init($url);

// 设置cURL选项
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: API key ' . $apiKey,
    'gstin: ' . $gstin
]);

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

// 执行cURL请求并获取响应
$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'cURL错误: ' . curl_error($ch);
    exit;
}

curl_close($ch);

// 解码JSON响应
$responseData = json_decode($response, true);

if (json_last_error() !== JSON_ERROR_NONE) {
    die('JSON解码错误: ' . json_last_error_msg());
}

// 调试API响应
echo "<script>console.log('API Response: " . addslashes(json_encode($responseData)) . "');</script>";

// 检查认证错误
if (isset($responseData['status']) && $responseData['status'] === 'error' && isset($responseData['message'])) {
    die('API错误: ' . $responseData['message']);
}

// 插入数据到数据库 

    $pdo->commit();
    echo '数据插入成功';
} catch (Exception $e) {
    $pdo->rollBack();
    echo '数据插入失败: ' . $e->getMessage();
}
?>

PHP请求的API响应

{"status":0,"message":"请求中提供的用户凭证无效。"}

Postman成功响应JSON

{
    "status": 1,
    "uuid": "cc1e4f5d-43ca-4373-9fd4-6e059fb6716a",
    "message": "EWB Generated",
    "alert": "",
    "validUpto": "06/08/2024 11:59:00 PM",
    "ewayBillNo": 171010516152,
    "ewayBillDate": "05/08/2024 07:16:00 PM",
    "EWayBillPdfUrl": "/~fnsjdjszvw/a/eway-bill/cc1e4f5d-43ca-4373-9fd4-6e059fb6716a/ewb/.pdf/",
    "EWayBillQrCodeUrl": "/~fnsjdjszvw/a/ewaybill/cc1e4f5d-43ca-4373-9fd4-6e059fb6716a/qr-code/",
    "Distance": "100"
}

排查建议

  • 核对URL参数编码:对比PHP生成的URL和Postman的请求URL,确认username和password的编码结果完全一致,重点检查特殊字符(如空格、&、%)的处理。
  • 验证GSTIN完整性:代码中$gstin值为29AAFCC9980M1,但请求JSON中的fromGstin是29AAFCC9980M1ZR,检查Postman使用的GSTIN是否完整,是否因PHP中GSTIN缺失后缀导致验证失败。
  • 检查请求头一致性:对比Postman和PHP的请求头,重点确认Authorization格式(API key是否完整,原代码中API key疑似少一位)、gstin字段的大小写和值是否匹配。
  • 输出完整请求日志:在PHP中添加代码输出完整请求信息,和Postman逐字段对比:
    // 在curl_exec前添加
    echo "<pre>请求URL: $url</pre>";
    echo "<pre>请求头: " . print_r(curl_getinfo($ch, CURLINFO_HEADER_OUT), true) . "</pre>";
    
  • 清理凭证前后空格:数据库取出的凭证可能包含隐形空格,使用trim()处理后再传入URL:
    $apiUsername = trim($user['username']);
    $apiPassword = trim($user['password']);
    
  • 测试SSL验证设置:尝试开启SSL验证(注释掉CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST的设置),部分API会因SSL验证关闭拒绝请求。

内容的提问来源于stack exchange,提问作者Syed Mujahid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:57:00