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

无法向HMRC测试API提交VAT Return,请求排查代码问题

HMRC VAT API提交VAT Return报错排查

问题场景

我正在使用HMRC VAT API提交VAT Return,最初的代码如下:

$vrn = 'test';
$endpoint = 'https://test-api.service.hmrc.gov.uk/organisations/vat/'.$vrn.'/returns'; 
$periodKey = 'A001';
$authToken = $access_token;// it is $token_data['access_token']

$vatReturnData = json_encode([
"periodKey" => $periodKey,
"vatDueSales" => 105.5,
"vatDueAcquisitions" => -100.45,
"totalVatDue" => 5.05,
"vatReclaimedCurrPeriod" => 105.15,
"netVatDue" => 100.1,
"totalValueSalesExVAT" => 300,
"totalValuePurchasesExVAT" => 300,
"totalValueGoodsSuppliedExVAT" => 3000,
"totalAcquisitionsExVAT" => 3000,
"finalised" => true
]);

$vatReturnJson = json_encode($vatReturnData);

$headers = [
'Accept: application/vnd.hmrc.1.0+json',
'Authorization: Bearer ' . $authToken, 
'Content-Type: application/json', 
'Content-Length: ' . strlen($vatReturnJson)
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vatReturnData);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
$response = curl_exec($ch);

if ($response === false) {
echo 'Error: ' . curl_error($ch). ' '. show_line_number();
} else {
echo 'Response: ' . $response. ' '. show_line_number();
}
curl_close($ch);

授权后后台执行约1分钟后重定向至我的网站,显示错误:Error: Recv failure: Connection reset by peer 125。

随后我修改代码,将$vatReturnData改为数组:

$vatReturnData = array(
"periodKey" => $periodKey,
"vatDueSales" => 105.5,
"vatDueAcquisitions" => -100.45,
"totalVatDue" => 5.05,
...
);

修改后收到响应:Response: {"code":"INTERNAL_SERVER_ERROR","message":"An internal server error occurred"}。

问题根源

1. 重复JSON编码导致格式与长度不匹配

最初代码中,先将数组编码为JSON字符串存入$vatReturnData,接着又对这个字符串再次执行json_encode得到$vatReturnJson,同时请求头的Content-Length使用的是二次编码后的字符串长度,但实际POST的内容是一次编码的$vatReturnData。这会导致:

  • 服务器收到的内容长度与声明的长度不符,触发连接重置
  • 即使长度巧合匹配,二次编码的内容会变成字符串嵌套的无效JSON,不符合API数据格式要求

2. 直接传递数组导致请求格式错误

修改为直接传递数组时,cURL默认会将数组编码为multipart/form-data格式,但HMRC API要求的是application/json格式,服务器无法正确解析请求体,因此返回内部错误。

3. 不必要的HTTP版本指定

手动指定CURL_HTTP_VERSION_1_1没有必要,cURL会自动协商最优的HTTP版本,多余的设置可能引发兼容性问题。

修复后的代码

$vrn = 'test';
$endpoint = 'https://test-api.service.hmrc.gov.uk/organisations/vat/'.$vrn.'/returns'; 
$periodKey = 'A001';
$authToken = $access_token; // 对应$token_data['access_token']

// 构造原始数据数组
$vatReturnArray = [
    "periodKey" => $periodKey,
    "vatDueSales" => 105.5,
    "vatDueAcquisitions" => -100.45,
    "totalVatDue" => 5.05,
    "vatReclaimedCurrPeriod" => 105.15,
    "netVatDue" => 100.1,
    "totalValueSalesExVAT" => 300,
    "totalValuePurchasesExVAT" => 300,
    "totalValueGoodsSuppliedExVAT" => 3000,
    "totalAcquisitionsExVAT" => 3000,
    "finalised" => true
];

// 仅执行一次JSON编码
$vatReturnJson = json_encode($vatReturnArray);

$headers = [
    'Accept: application/vnd.hmrc.1.0+json',
    'Authorization: Bearer ' . $authToken, 
    'Content-Type: application/json'
    // 无需手动设置Content-Length,cURL会自动计算并添加
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vatReturnJson);
// 移除不必要的HTTP版本强制设置
$response = curl_exec($ch);

if ($response === false) {
    echo 'Error: ' . curl_error($ch) . ' ' . show_line_number();
} else {
    echo 'Response: ' . $response . ' ' . show_line_number();
}
curl_close($ch);

额外检查点

  • 确保$vrn使用的是测试环境下的有效编号,而非占位符'test'
  • 确认$authToken是具备VAT提交权限的有效访问令牌
  • 若仍有问题,可添加curl_setopt($ch, CURLOPT_VERBOSE, true);开启cURL调试模式,查看详细请求日志定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:13:19