Reputation: 1931
I am trying to use CURL to send a file to PANDADOCS via their Create Document from File API call : https://developers.pandadoc.com/reference/create-document-from-pdf.
As well as sending the file I need to send a data object containing recipients etc. as JSON as part of the multipart/form-data string. I am unsure how to setup this call properly and I keep getting various error messages returned from their API such as "There is field called file"
Here is what I have so far:
public function createDocument()
{
$p = getmypid();
$m = "({$p}): PandaDoc::create document: ";
$postfields = array();
$postfields['name'] = $this->document->name;
$postfields['file'] = $this->document->file; //base 64 encoded PDF
$recipients = array(
array(
'email' => '[email protected]',
'first_name' => 'Andrew',
'last_name' => 'Mcdoogle',
'role' => 'user',
'signing_order' => 1
)
);
$data = array();
$data['recipients'] = $recipients;
$owner = array(
"email" => "[email protected]"
);
$data['owner'] = $owner;
$postfields['data'] = json_encode($data);
$header = array("Authorization: API-Key {$this->api_key}", "Content-Type: multipart/form-data", "accept" => "application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$res = curl_exec($ch);
if ($res === false) {
$errno = curl_errno($ch);
$error = curl_error($ch);
error_log("{$m}cURL error: {$error} ({$errno})");
throw new Exception("{$m}cURL error: {$error} ({$errno})");
}
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch);
error_log("{$m}Results from PandaDoc: {$res}");
$response = json_decode($res);
return $response;
}
Can anybody tell me what I am doing wrong?
Upvotes: 1
Views: 1351
Reputation: 5663
This is wrong:
$postfields['data'] = json_encode($data);
I found their API documentation to be disconcerting.
Short tutorial:
Here is a simple multipart/form-data HTML form:
Below I translate this form to curl.
<form action="<url>" method="post" enctype="multipart/form-data">
<input type="text" name="name1" value="value1" >
<input type="text" name="name2" value="value2" >
<input type="text" name="name3" value="value3" >
<button type="submit">submit</button>
</form>
To send this in curl you have to put the form-data in the postfields.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '<url>');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "-----------------------------3303153187906175792551542585\r\nContent-Disposition: form-data; name=\"name1\"\r\n\r\nvalue1\r\n-----------------------------3303153187906175792551542585\r\nContent-Disposition: form-data; name=\"name2\"\r\n\r\nvalue2\r\n-----------------------------3303153187906175792551542585\r\nContent-Disposition: form-data; name=\"name3\"\r\n\r\nvalue3\r\n-----------------------------3303153187906175792551542585--\r\n");
$response = curl_exec($ch);
This is the request header:
Content-Length: 408
Content-Type: application/x-www-form-urlencoded
Accept: */*
Host: my_curl_test_site.com
X-Https: 1
And this is the request body:
-----------------------------3303153187906175792551542585
Content-Disposition: form-data; name="name1"
value1
-----------------------------3303153187906175792551542585
Content-Disposition: form-data; name="name2"
value2
-----------------------------3303153187906175792551542585
Content-Disposition: form-data; name="name3"
value3
-----------------------------3303153187906175792551542585
I base64 encode a pdf like this:
$pdf = base64_encode(file_get_contents('example.pdf'));
For your PandaDoc API
Here is the document field, notice the $pdf from above.
------BoundaryXXXXXXXXX
Content-Disposition: form-data; name="file"; filename="Sample PandaDoc PDF with Field Tags.pdf"
Content-Type: application/pdf;
$pdf
------BoundaryXXXXXXXXX
Your content-type may need to be application/pdf;base64
Their example use the binary data.
And here are your data fields
------BoundaryXXXXXXXXX
Content-Disposition: form-data; name="data"
{
"name": "My minimal document",
"url": "https://example.com/path/to/mydocument.pdf",
"recipients": [
{
"email":"[email protected]"
}
],
"parse_form_fields": false
}
------BoundaryXXXXXXXXX
Source: https://developers.pandadoc.com/docs/upload-and-send-a-local-pdf
Upvotes: 2