我正在使用Docusign的REST API来创建和发送信封。我已将包含requireAcknowledgment的eventNotifications包含为true,以便在状态发生变化时从Docusign获取请求。我在开发和测试时使用了ngrok,一切都按预期工作。
我已经在线移动了该项目,并使用https编辑了eventNotification的网址以及所有回调都记录在Docusign管理员的失败部分中面板。
管理面板中显示的错误消息是 -
' https://xxx.xxxxxxx.com/webhook.php ::错误 - 远程服务器 返回错误:(400)错误请求。'
我已经下载了失败的请求的xml正文,并尝试通过邮递员发送请求,并且按预期工作。我已经尝试了一切来调试这个错误,并且在我的结尾没有发现错误。
编辑: 我尝试过的代码与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);
答案 0 :(得分:0)
抱歉,您在使用webhook功能时遇到了很多麻烦。希望这个答案会有所帮助。
<?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!");
}
将其存储为您的Web服务器目录中的ok.php
。然后尝试(从不同网络上的浏览器)到达https://yourserver.company.com/ok.php
您应该在浏览器窗口中看到“确定”。
然后在您的Envelopes :: create call的eventNotification
部分使用相同的网址,看看它是否全部有用。您应该在Connect日志等中看到成功。
使用您的php监听器应用程序排除许多问题(如诊断人员所说)。
您应用的平台错误。这是PHP软件堆栈设置的问题,导致堆栈(不是您的PHP应用程序本身)拒绝请求。
通常的指标是您的网络服务器的错误日志。你看过了吗?日志行中有哪些内容可以显示从服务器到DocuSign的400响应?如果您没有看到对DocuSign的400响应,那么Web服务器的设置就出现了问题。
使用默认设置时,PHP和其他堆栈的常见平台错误是maximum_post_size_exceeded。如果您已要求DocuSign在通知消息中包含您的信封文件,则会发生这种情况。
一个好的测试是临时更改信封创建代码,使其不包含通知消息中的文档。
修复:一个好的解决方法是不在通知消息中包含信封文档。相反,在收到消息后,进行单独的API调用以检索文档。
另一个解决方法是增加最大贴身尺寸。您可能还需要在PHP settings和基础Web服务器的设置中增加它。 (顺便说一句,您使用的是哪个Web服务器?)
您正在处理服务器/ 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程序。这可能不会发生在你的情况下,但其他人可能会遇到这种情况。
我想我接下来会为你的PHP程序添加更多的调试语句,试着去理解它发生了什么。您可以使用error-log执行此操作 或者从我的示例(上面)复制技术并写入/ tmp中的文件。 (假设有Linux服务器。)
另一种选择是增加php堆栈本身或web服务器或两者的调试级别。
400通常表示DocuSign已到达您的服务器并返回400状态代码。这可以通过检查您的服务器日志(常规或错误)来确认,应该有匹配的条目。
如果您的服务器日志中没有条目,但上面的“ok.php”程序确实有效,那么是时候从PHP程序中注释掉大块代码,然后再做另一个测试来自DocuSign。最后,使用binary-search technique(参见本文中的第8步),您会找到导致问题的代码。
将代码作为二进制搜索的一部分来查找错误是一种非常常见且功能强大的调试技术。
HTH,拉里