文档签名事件通知失败,出现错误 400



我正在使用Docusign的REST API来创建和发送信封。我已经将事件通知与要求确认作为 true,以便在状态发生变化时从 Docusign 获取请求。我在开发和测试时使用了 ngrok,一切都按预期工作。

我已经将项目移到了网上,并使用https编辑了eventNotification的url到实时url,这就是所有回调都记录在Docusign管理面板中失败部分的时候。

管理面板中显示的错误消息是 -

'https://xxx.xxxxxxx.com/webhook.php :: 错误 - 远程服务器 返回错误:(400( 错误请求。

我已经下载了失败请求的 xml 正文并尝试通过邮递员发送请求,它按预期工作。Iv'e尝试了一切方法来调试此错误,但在我最后没有发现错误。

编辑: 我尝试过的代码与 DocuSign 的 webhook 示例页面中的代码相同 -

$data = file_get_contents('php://input');
$xml = simplexml_load_string ($data, "SimpleXMLElement", LIBXML_PARSEHUGE);
$envelope_id = (string)$xml->EnvelopeStatus->EnvelopeID;
$time_generated = (string)$xml->EnvelopeStatus->TimeGenerated;
$files_dir = getcwd() . '/' . $this->xml_file_dir;
if(! is_dir($files_dir)) {mkdir ($files_dir, 0755);}
$envelope_dir = $files_dir . "E" . $envelope_id;
if(! is_dir($envelope_dir)) {mkdir ($envelope_dir, 0755);}
$filename = $envelope_dir . "/T" . 
str_replace (':' , '_' , $time_generated) . ".xml"; // substitute _ for : for windows-land
$ok = file_put_contents ($filename, $data);
if ($ok === false) {
error_log ("!!!!!! PROBLEM DocuSign Webhook: Couldn't store $filename !");
exit (1);
}
// log the event
error_log ("DocuSign Webhook: created $filename");
if ((string)$xml->EnvelopeStatus->Status === "Completed") {
// Loop through the DocumentPDFs element, storing each document.
foreach ($xml->DocumentPDFs->DocumentPDF as $pdf) {
$filename = $this->doc_prefix . (string)$pdf->DocumentID . '.pdf';
$full_filename = $envelope_dir . "/" . $filename;
file_put_contents($full_filename, base64_decode ( (string)$pdf->PDFBytes ));
}
}

我还尝试使用仅将标头设置为 200 的简单代码

http_response_code(200);

抱歉,您在使用网络钩子功能时遇到了很多麻烦。希望这个答案会有所帮助。

1. 尝试测试PHP程序来检查连接性等:

<?php
header('Content-Type: text/html');
echo "OK!";
$h = fopen('/tmp/listener_access.log', 'a');
if ($h) {
$now = DateTime::createFromFormat('U.u', microtime(true), new DateTimeZone('UTC'));
fwrite ($h,  $now->format ("Y-m-d_l.h.i.s.v "));
fwrite($h, $_SERVER["REMOTE_ADDR"] . " " . $msg . "n");
fclose($h);
} else {
error_log ("### Could not open log file!");
}

将其作为ok.php存储在 Web 服务器目录中。然后尝试(从其他网络上的浏览器(访问https://yourserver.company.com/ok.php您应该在浏览器窗口中看到"确定"。

然后在 Envelopes::create 调用的eventNotification部分中使用相同的 URL,看看它是否一切正常。您应该在连接日志等中看到成功。

2. 逐步调试 PHP 监听

器您的 php 侦听器应用程序有许多问题需要排除(正如诊断师所说(。

  1. 与侦听器的基本连接。由于DocuSign从您的应用程序收到400错误,因此连接正常。
  2. 应用出现平台错误。这是您的 PHP 软件堆栈设置的问题,导致堆栈(而不是您的 PHP 应用程序本身(拒绝请求。

    通常的指示器是Web服务器的错误日志。你看过吗?在日志记录行上,您会看到从服务器到 DocuSign 的 400 响应是什么?如果您没有看到对 DocuSign 的 400 响应,则您的 Web 服务器的设置有问题。

  3. 使用默认设置时,PHP 和其他堆栈的常见平台错误是maximum_post_size_exceeded。如果您已请求DocuSign在通知消息中包含信封的文档,则会发生这种情况。

    一个好的测试是暂时更改信封创建代码,以不在通知消息中包含文档。

    修复:一个好的解决方法是不在通知消息中包含信封文档。相反,在收到消息后,请进行单独的 API 调用以检索文档。

    另一个解决方法是增加最大帖子正文大小。您可能还需要在 PHP 设置和底层 Web 服务器的设置中增加它。(顺便问一下,您使用的是哪个Web服务器?

  4. 您正在服务器/php 应用程序的响应线程中处理传入通知。这真的不是最好的技术(我将在未来使用这些信息更新 DocuSign 示例页面。

最好的技术是使用以下模式:

1. Receive the incoming notification message from DocuSign
2. Put the message onto a reliable FIFO queue
3. Respond to DocuSign with a 200 response.

Then, in a separate thread of execution, a 
different software application "works off" the 
entries in the queue.

例如,您的 Web 服务器可能会使您的 PHP 程序超时。在您的情况下,这可能没有发生,但其他人可能会遇到这种情况。

  1. 我想接下来我会在你的PHP程序中添加更多的调试语句,以尝试了解它发生了什么。您可以使用错误日志执行此操作 或者从我的示例(上面(中复制技术并写入/tmp 中的文件。(假设是Linux服务器。

    另一种选择是提高 php 堆栈本身和/或 Web 服务器的调试级别。

3.最后的想法

DocuSign 日志中的 400 通常表示 DocuSign 到达您的服务器并返回 400 状态代码。这可以通过检查服务器日志(常规或错误(来确认,应该有一个匹配的条目。

如果您的服务器日志中没有条目,但上面的"ok.php"程序确实有效,那么是时候从您的 PHP 程序中注释掉大块代码,然后从 DocuSign 进行另一次测试。最终,使用二进制搜索技术(请参阅本文中的步骤 8(,您可以找到导致问题的代码。

注释掉代码作为二进制搜索的一部分以查找错误是一种非常常见且功能强大的调试技术。

HTH, 拉里

最新更新