I'm trying to build a custom accounting report using the PayPal NVP API that will get all transactions for a specific date range.
My code:
$headers = array(
'USER' => $production_user,
'PWD' => $production_pass,
'SIGNATURE' => $production_sig
);
$nvp = array(
'METHOD' => 'TransactionSearch',
'TRANSACTIONCLASS' => 'RECEIVED',
'STARTDATE' => '2016-12-01T00:00:00Z',
'ENDDATE' => '2016-12-31T00:00:00Z'
);
$request_url = "https://api-3t.paypal.com/nvp?".http_build_query($nvp);
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HEADER, $headers);
curl_setopt($curl, CURLOPT_POST, 1);
$result = curl_exec($curl);
$result = explode("&", $result);
foreach($result as $f=>$v){
$t = explode("=", $v);
echo $t[0]." => ".urldecode($t[1]);
echo "<br>";
}
Here is what gets printed:
HTTP/1.1 200 OK Date: Fri, 10 Feb 2017 19:51:20 GMT Server: Apache X-PAYPAL-OPERATION-NAME: X-PAYPAL-API-RC: 10001 Connection: close Cache-Control: max-age => 0, no-cache, no-store, must-revalidate Pragma: no-cache HTTP_X_PP_AZ_LOCATOR: slcb.slc Paypal-Debug-Id: 484a759b46e4a Set-Cookie: X-PP-SILOVER
CORRELATIONID => some_random_characters
ACK => Failure
L_ERRORCODE0 => 10001
L_SHORTMESSAGE0 => Internal Error
L_LONGMESSAGE0 => Timeout processing request
Any assistance with this issue would be greatly appreciated!
You are using a post request and have not post data.
I do not know what PayPal wants to see but I'm guessing it's not what you are sending.
Some things to try:
If you need to pass the USER, PWD, and SIGNATURE in the Request Header do it like this:
$request = array();
$request[] = "USER: $production_user";
$request[] = "PWD: $production_pass";
$request[] = "SIGNATURE: $production_sig";
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
If the $nvp parameters need to be post data, try this:
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvp);
The $nvp can be passed as a query string in the post data also.
$query = http_build_query($nvp);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
The difference is the Content-Type.
The first method:
Content-Type: application/x-www-form-urlencoded
The second method:
Content-Type: multipart/form-data
To help in trouble shooting it would be good to see both the request and response header.
Use these options to get the headers:
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
The Request Header will be in the 'curl_getinfo()'
curl_setopt($ch, CURLOPT_HEADER, true);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
var_export($info);
The above gives lots of other details of the request. If you only want to see the header:
$request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
To get the response header:
$result = curl_exec($ch);
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$response = substr($result ,0,$skip);
$result = substr($result ,$skip);
Related
unfortunately I get no good response from the api provider.
No I need your support. I build a test extension in "wiso mein büro" for testing.
I would like to create an order with php and this api:
https://api.meinbuero.de/openapi/documentation/#/orders/postorderCreate
My code:
$wisoApiKey = "XXX";
$wisoSecretApiKey = "XXX";
$wisoOwnershipId = "XXX";
$positionen[] = array ('id' => 769541, 'amount' => 60);
$ch = curl_init('https://api.meinbuero.de/openapi/order/');
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json" , "Authorization: Bearer ".$wisoToken));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERPWD, $wisoApiKey . ":" . $wisoSecretApiKey);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(
array (
"customerId" => 1698487,
"articles" => $positionen
)
));
$createOrder = curl_exec($ch);
curl_close($ch);
echo '<pre>';
print_r($createOrder);
Result:
HTTP/1.1 500 Internal Server Error
Server: nginx/1.19.0
Date: Mon, 09 Aug 2021 18:38:49 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Strict-Transport-Security: max-age=7776000; includeSubDomains; preload
Access-Control-Allow-Origin: *
All other apis works fine like create, get customer, create invoice from order, ...
Only the api create order doesn't work for me.
I don't know why ...
I am trying to send a PATCH request through cURL and i get this response:
HTTP/1.1 400 Bad Request Server: nginx Date: Fri, 01 Apr 2016 09:16:03 GMT Content-Type: application/problem+json Content-Length: 198 Connection: keep-alive X-Powered-By: PHP/5.6.19 {"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Internal Server Error","status":500,"detail":"setValidationGroup() expects a list of valid input names; \"\" was not found"}
My code:
sendData("2016-10-01", "2016-10-02", "1234");
function sendData($from, $to, $property){
$data = array(
"from" => $from,
"to" => $to,
"booking_id" => 3
);
$data = json_encode($data);
echo $data . "<br>";
$url = "https://api.urlhost.com/property/".$property."/avail";
echo $url. "<br>";
$headers = array('Authorization: Basic dGVhQGJsdW1lbnJpdmllcmEuOIT6Qmx1bQVucm17aAKyzTtyfw==','Content-Type: application/json-patch+json');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_HEADER, true);
$response = curl_exec($curl);
echo ($response) . PHP_EOL;
//print_r(curl_getinfo($ch));
curl_close($curl);
}
When i echo the data and url i get these:
{"from":"2016-10-01","to":"2016-10-02","booking_id":3}
https://api.urlhost.com/property/1234/avail
But still is giving me this error. Any suggestions why this might happen?
I'm using the Imgur API to upload images. They have detailed in their API docs that each request (when I upload an image via their API) also has response headers, which will tell me how much credit the account has left.
I need to return the HTTP response header X-RateLimit-ClientRemaining. Here is the code I am currently using to get the cURL body back:
$filename = dirname(realpath(__FILE__))."/images/$value";
$client_id = "f*************c";
$handle = fopen($filename, "r");
$data = fread($handle, filesize($filename));
$pvars = array('image' => base64_encode($data));
$timeout = 30;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $pvars);
$out = curl_exec($curl);
curl_close ($curl);
$pms = json_decode($out,true);
$url=$pms['data']['link'];
if($url!=""){
// add to success
array_push($success, $url);
}
else {
// add to fail
$p = $value.' failed, error: '.$pms['data']['error'];
array_push($fail, $p);
}
($value is coming from a loop I have not included)
Why not try
curl_setopt($curl, CURLOPT_HEADER, 1);
To receive both headers and content. All you need to do is parse headers from the $out variable.
Here's fully working example while fetching from Google:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
header('Content-Type: text/plain; charset=utf-8');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://www.google.com/');
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_POST, 0);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$out = curl_exec($curl);
curl_close ($curl);
$out = preg_split('/(\r?\n){2}/', $out, 2);
$headers = $out[0];
$headersArray = preg_split('/\r?\n/', $headers);
$headersArray = array_map(function($h) {
return preg_split('/:\s{1,}/', $h, 2);
}, $headersArray);
$tmp = [];
foreach($headersArray as $h) {
$tmp[strtolower($h[0])] = isset($h[1]) ? $h[1] : $h[0];
}
$headersArray = $tmp; $tmp = null;
// $headersArray contains your headers
print_r($headersArray);
?>
This produces:
Array
(
[http/1.1 200 ok] => HTTP/1.1 200 OK
[date] => Thu, 29 Oct 2015 13:26:39 GMT
[expires] => -1
[cache-control] => private, max-age=0
[content-type] => text/html; charset=ISO-8859-1
[p3p] => CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
[server] => gws
[x-xss-protection] => 1; mode=block
[x-frame-options] => SAMEORIGIN
[set-cookie] => NID=72=lw6pIMe05MoXu3aykbPi0BR9gZomWqTXBwsk6VG7xtLbLLeWc0I__CLGydE-auttR0G8VulKoZOTrv4eAZovJJi9QyB5hgxBue9pLWcX794Iv6gPlM2QaL9I2t6tjtrADtczAZpHhbnLvjmeDn_AmRj0xKkFPrMhYR84C5lNgzgo1iJpzr5qG2y6xg; expires=Fri, 29-Apr-2016 13:26:39 GMT; path=/; domain=.google.com; HttpOnly
[alternate-protocol] => 443:quic,p=1
[alt-svc] => quic="www.google.com:443"; p="1"; ma=600,quic=":443"; p="1"; ma=600
[accept-ranges] => none
[vary] => Accept-Encoding
[transfer-encoding] => chunked
)
From your example above, you'd seek $headersArray['x-ratelimit-clientremaining'];
Hope that helps.
Edit: here's the quick way (because your response does not contain linefeeds):
$matches = null;
preg_match('/X-RateLimit-ClientRemaining:\s*(\d+)/i', $out, $matches);
echo sprintf('X-RateLimit-ClientRemaining: %u', $matches[1]);
Produces:
X-RateLimit-ClientRemaining: 11850
I'm trying to get all the contacts from the current user connected via the Oauth2 Microsoft Online, i did the Oauth2 thing right but when i call the url for the api http://outlook.office.com/api/v1.0/me/contacts I got an empty string and this in the Header:
HTTP/1.1 403 Forbidden
Cache-Control: private
Content-Length: 0
Server: Microsoft-IIS/8.5
Set-Cookie: ClientId=QPAIYPSBRKGUWYWEQFBAA; expires=Tue, 27-Sep-2016 12:07:04 GMT; path=/; secure; HttpOnly
request-id: d24bcf29-372e-4bbc-bb7c-f753cde1d1dc
X-CasErrorCode: UserNotFound
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-FEServer: AMSPR03CA0038
Nothing else.
Here is my code in PHP with everything for OAuth. The code use Laravel :)
public function outlook(Request $request)
{
if($request->session()->has('tokenOutlook'))
{
return redirect('/contact/outlook/all');
}
else
{
if(!$request->has('code'))
{
return redirect("https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=".env('APPIDOUTLOOK')."&redirect_uri=".secure_url('/contact/outlook')."&response_type=code&scope=".urlencode("https://outlook.office.com/Contacts.Read"));
}
else
{
$curl = curl_init("https://login.microsoftonline.com/common/oauth2/v2.0/token");
curl_setopt($curl, CURLOPT_POST, true);
$postdata = array(
"client_id" => env('APPIDOUTLOOK'),
"code" => $request->get('code'),
"grant_type"=>"authorization_code",
"scope" => urlencode("https://outlook.office.com/Contacts.Read"),
"client_secret" => env('APPSECRETOUTLOOK')
);
$fields_string = '';
foreach($postdata as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$oauth_token = curl_exec($curl);
curl_close($curl);
$oauth_token = json_decode($oauth_token);
//dd($oauth_token)
$request->session()->put('tokenOutlook', $oauth_token->access_token);
return redirect('/contact/outlook/all');
}
}
}
public function showOutlook(Request $request)
{
if($request->session()->has('tokenOutlook'))
{
//dd($request->session()->get('tokenOutlook'));
$curl = curl_init('https://outlook.office.com/api/v1.0/me/contacts');
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Bearer ".$request->session()->get('tokenOutlook')));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$contacts = curl_exec($curl);
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($contacts, 0, $header_size);
//var_dump($header);
//dd($curl);
curl_close($curl);
$contacts = json_decode($contacts);
$array_contacts = [];
return $array_contacts;
}
else
{
return redirect('/contact/outlook');
}
}
Why do i get an UserNotFound error with /me ? :(
I have resolved my problem by adding redirect_uri in post data...
$postdata = array(
"client_id" => env('APPIDOUTLOOK'),
"code" => $request->get('code'),
"grant_type"=>"authorization_code",
"scope" => urlencode("https://outlook.office.com/Contacts.Read"),
"client_secret" => env('APPSECRETOUTLOOK')
"redirect_uri" => secure_url('/contact/outlook')
);
Running Out Of Sanity
I have looked high and low and lost a bit of my life and a lot of my sanity trying to return a cURL POST request. Everything works fine except I cannot remove the headers. Oh yes I have tried
curl_setopt($ch, CURLOPT_HEADER, false);
What worse is that when I try
$headerLength = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
I get a return of 25 which is completely wrong. Please help I am at my wits end with this one.
So I call this method
$service = new RestfulService($Url1);
$response = $service->request('', 'POST', $tokenXml, null,
array(CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_ENCODING =>'UTF-8'));
Which in turn calls (using SilverStripe framework)
public function curlRequest($url, $method, $data = null, $headers = null, $curlOptions = array()) {
$ch = curl_init();
$timeout = 5;
$sapphireInfo = new SapphireInfo();
$useragent = 'SilverStripe/' . $sapphireInfo->Version();
$curlOptions = $curlOptions + (array)$this->config()->default_curl_options;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
if(!ini_get('open_basedir')) curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
//include headers in the response
curl_setopt($ch, CURLOPT_HEADER, true);
// Add headers
if($this->customHeaders) {
$headers = array_merge((array)$this->customHeaders, (array)$headers);
}
if($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Add authentication
if($this->authUsername) curl_setopt($ch, CURLOPT_USERPWD, $this->getBasicAuthString());
// Add fields to POST and PUT requests
if($method == 'POST') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
} elseif($method == 'PUT') {
$put = fopen("php://temp", 'r+');
fwrite($put, $data);
fseek($put, 0);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_INFILE, $put);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data));
}
// Apply proxy settings
if(is_array($this->proxy)) {
curl_setopt_array($ch, $this->proxy);
}
// Set any custom options passed to the request() function
curl_setopt_array($ch, $curlOptions);
// Run request
$rawResponse = curl_exec($ch);
if (curl_error($ch)) var_dump(curl_error($ch));
$response = $this->extractResponse($ch, $rawResponse);
curl_close($ch);
return $response;
}
When I dump the response, the remove header command only removes the first few characters. Like so...
object(RestfulService_Response)[1065]
protected 'simpleXML' => null
protected 'cachedResponse' => boolean false
protected 'statusCode' => int 100
protected 'statusDescription' => string 'Continue' (length=8)
protected 'headers' =>
array (size=0)
empty
protected 'body' => string 'ontrol: no-cache
Pragma: no-cache
Content-Length: 3593
Content-Type: application/soap+xml; charset=utf-8
Expires: Fri, 20 Sep 2013 01:14:14 GMT
Server: Microsoft-IIS/7.5
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
X-XSS-Protection: 0
PPServer: PPV: 30 H: CO1IDOLGN62 V: 0
Date: Fri, 20 Sep 2013 01:15:13 GMT
Connection: close
�<?xml version="1.0" encoding="utf-8" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envel
Has it got anything to do with the strange character before the
Update: I have checked this code on my colleagues computer, he doesn't have any problems. I am running WAMP my colleague is on a MAC, could there be any set up issues? I have downloaded the most recent curl.dll and added it to my php library, still no cigar.
Any ideas???
In my case the encoding was incorrect I needed to add the following option
curl_setopt($ch, CURLOPT_SSLVERSION, 3)
Works fine now