GuzzleHttp - 400 error exception but with curl working perfectly - guzzle6

I'm calling a third party rest API with GuzzleHttp but it gives me a 400 Bad Request every time.
Development environment:
Laravel / PHP framework
Guzzle version in composer.json file - "guzzlehttp/guzzle": "^6.3"
Ubuntu 16.04 LTS
Guzzle call to URL with data:
try{
$client = new \GuzzleHttp\Client();
$res= $client->request('post',
env('FLIGHT_API').'FlightSearch',
['headers' => ['Content-Type' => 'application/json' , 'Accept' => 'application/json'],'form_params' => $body]);
}catch (ClientException $e){
$response['status'] = false;
$response['message'] = $e->getMessage().$e->getCode();
return $response;
}
Guzzle response:
{
"status": false,
"message": "Client error: `POST http://stagingapi.trip.com/Search` resulted in a `400 Bad Request` response:\n\ufeff<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3 (truncated...)\n400"
}
So, at last I tried same API with curl and it's working perfect and get result.
Curl code with URL and data:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => env('FLIGHT_API').'FlightSearch',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application/json",
"Accept: application/json"
),
));
$response = curl_exec($curl);
//return $response;
$err = curl_error($curl);
curl_close($curl);
if($response){
return json_decode($response , true);
}
return $err;
How can I determine where the fault is?

You need
'json' => $body
instead of
'form_params' => $body

Related

Linkedin cURL API for image upload returns status code 400 (Bad Request)

i am using Linkedin cURL API for image upload but it returns status code 400 (Bad Request).
i tried solution proposed on flowing thread but still getting response code 400
Linkedin v2 API Image upload get error 400 Bad Request
There are two steps here.
Step-1: i am successfully getting uploadUrl from following API call,
Step-2: posting image to this uploadUrl.
Step-1 code:
//Code to get uploadUrl
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.linkedin.com/v2/assets?action=registerUpload',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"registerUploadRequest":{
"owner":"urn:li:person:'.$linked_in_user_id.'",
"recipes":[
"urn:li:digitalmediaRecipe:feedshare-image"
],
"serviceRelationships":[
{
"identifier":"urn:li:userGeneratedContent",
"relationshipType":"OWNER"
}
],
"supportedUploadMechanism":[
"SYNCHRONOUS_UPLOAD"
]
}
}',
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer '.$linkedin_access_tocken,
'Content-Type: application/json',
'Cookie: lidc="b=VB25:s=V:r=V:a=V:p=V:g=3710:u=27:x=1:i=1661712819:t=1661796456:v=2:sig=AQGuKhcP666UyP--ofMWcO6dE4bNJDzG"; bcookie="v=2&b6c03c49-9be3-414c-897c-ab62b7e38d54"; lidc="b=VB73:s=V:r=V:a=V:p=V:g=2926:u=1:x=1:i=1661712702:t=1661799102:v=2:sig=AQGumNfwXwaDet2YXaOP51s4P3iU7Ob7"'
),
));
$response_register_upload = curl_exec($curl);
$response_register_upload = (array)json_decode($response_register_upload,true);
$uploadUrl = $response_register_upload["value"]["uploadMechanism"]["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"]["uploadUrl"];
echo "<br>uploadUrl:<br>";
echo $uploadUrl;
curl_close($curl);
Step-2:
//Code for Upload image
if(!empty($uploadUrl))
{
$headers = array();
$headers[] = 'Authorization: Bearer '.$linkedin_access_tocken;
$headers[] = 'X-Restli-Protocol-Version: 2.0.0';
$headers[] = 'Content-Type: image/jpg';
$headers[] = 'media-type-family: STILLIMAGE';
$curl2 = curl_init();
curl_setopt_array($curl2, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => array('upload-file'=> './uploads/post_attachment/post-attachment20220707224012.jpg'),
CURLOPT_HTTPHEADER => $headers,
));
$response_image_upload = curl_exec($curl2);
echo "response_image_upload:<PRE>";
print_r($response_image_upload);
echo "</PRE>";
$code = curl_getinfo($curl2, CURLINFO_HTTP_CODE);
echo "<br>code:<br>";
echo $code;
if (curl_errno($curl2)) {
$error_msg = curl_error($curl2);
echo $error_msg;
}
curl_close($curl2);
Please help

How can I share Grafana dashboard with json data in php web application?

Using HTTP API to share dashboard from Grafana into another PHP web application's dashboard gives me JSON data using curl
Referred http://docs.grafana.org/http_api/dashboard/ and used GET /api/dashboards/uid/:uid
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_PORT => "3000",
CURLOPT_URL => here comes grafana dashboard url to share,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Basic YWRtaW46ZHluRWtvZGU=",
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err; ?>
<?php } else {
echo $response;
}
In the response get JSON data.
How can I use this json to get particular Grafana dashboard access on my web application?

Call Rest Api Using Zend\Http\Client Or Guzzle

I am calling magento2 API in laravel. Using curl, I am getting correct response but I want to call API using GuzzleHttp\Client or Zend\Http\Client.
How can I call my api using this, below is my curl code snippet:
$curl = curl_init();
$data=array('username'=>$vendordata['merchant_name'],'password'=>$vendordata['password'],'customer'=>['email'=>$vendordata['email'],"firstname"=> $vendordata['firstname'], "lastname"=> $vendordata['lastname']],"addresses"=> ["region"=> $vendordata['address'], "region_id"=> 0],"default_shipping"=> true,"default_billing"=>true,"telephone"=>$vendordata['contact_number']);
$postdata=json_encode($data);
curl_setopt_array($curl, array(
CURLOPT_URL => "http://10.10.10.7/magento2/rest/V1/customers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $postdata,
CURLOPT_HTTPHEADER => array(
"authorization: OAuth oauth_consumer_key=\"sganfgvr2naxwmh21jgi5ffijuci0207\",oauth_token=\"d16pdq1avr1rs7h9745rc0x6py65a2vt\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1518006201\",oauth_nonce=\"4ghORA\",oauth_version=\"1.0\",oauth_signature=\"Ztq5ErznqvCl18GomWv0F55t5OA%3D\"",
"cache-control: no-cache",
"content-type: application/json",
"postman-token: 5ec55151-3365-7ffc-a6a4-ce5fe5bc451f"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
First, open the terminal and run this command to install Guzzle
composer require guzzlehttp/guzzle
Then add these lines to include guzzle in the specific controller.
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
Now, create a method you want to run to call the API and put the below code
$client = new Client(); //GuzzleHttp\Client
$result = $client->post('your-request-uri', [
'form_params' => [
'sample-form-data' => 'value'
]
]);
That's it!
Docs explain this pretty well : https://github.com/guzzle/guzzle
Here is the complete code when using guzzlehttp instead of curl
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'http://10.10.10.7/magento2/rest/V1/customers', array(
headers' => [
'Authorization' => 'OAuth oauth_consumer_key="sganfgvr2naxwmh21jgi5ffijuci0207",oauth_token="d16pdq1avr1rs7h9745rc0x6py65a2vt",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1518006201",oauth_nonce="4ghORA",oauth_version="1.0",oauth_signature="Ztq5ErznqvCl18GomWv0F55t5OA%3D',
'Cache-Control' => 'no-cache',
'Postman-Token' => '5ec55151-3365-7ffc-a6a4-ce5fe5bc451f'
],
'json' => $postdata
));
You also have to install following dependencies in your laravel project for PSR-7 support and look at this stackoverflow question as a reference:
composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros
That caused by you didn't define the Content-Type as application/json on HTTP Header. Please try this
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'http://10.10.10.7/magento2/rest/V1/customers', array(
headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'OAuth oauth_consumer_key="sganfgvr2naxwmh21jgi5ffijuci0207",oauth_token="d16pdq1avr1rs7h9745rc0x6py65a2vt",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1518006201",oauth_nonce="4ghORA",oauth_version="1.0",oauth_signature="Ztq5ErznqvCl18GomWv0F55t5OA%3D',
'Cache-Control' => 'no-cache',
'Postman-Token' => '5ec55151-3365-7ffc-a6a4-ce5fe5bc451f'
],
'json' => $postdata
));
And don't forget to load the dependencies using composer
composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

Paypal, IPN/Webhooks create invoice in my paypal account, to send money

I want to create via IPN or Webhooks the following situation.
The user want to withdraw some money, when he clicks the button to withdraw, an invoice will be made in my Paypal account where I will have the option to Accept or Deny to send the money. After accept or deny, my app will receive an notification if the money was sent or not.
I am reading their documentation, but I don't find what I want.
I think you're a little bit confused with what PayPal features you would need for this.
IPN and Webhooks are post-transaction processing tools. They wouldn't trigger anything until AFTER an invoice was already created, a payment was received, a dispute was submitted, etc.
Also, you don't want to do this with the actual Invoicing API because PayPal charges higher fees for that.
If you provide your user with a button to withdrawal money you could trigger the payout directly on that action using the Payouts API.
You did not specify what language you are working with, but here's a sample of a PHP script that would trigger a payout:
<?php
$paypal_client_id = "your_client_id";
$paypal_secret = "your_secret";
$payee_email = "payee#example.com";
$amount = 10.00;
$currency = "USD";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paypal.com/v1/oauth2/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "grant_type=client_credentials",
CURLOPT_HTTPHEADER => array(
"Authorization: Basic " . base64_encode("$paypal_client_id:$paypal_secret"),
"Content-Type: application/x-www-form-urlencoded"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$access_token = json_decode($response)->access_token;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paypal.com/v1/payments/payouts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"sender_batch_header\": {\"sender_batch_id\":\"batch_" . time() . "\",\"email_subject\":\"You have a payment\"},\"items\":[{\"recipient_type\":\"EMAIL\",\"amount\":{\"value\":$amount,\"currency\":\"$currency\"},\"receiver\":\"$payee_email\",\"note\":\"Thank you.\",\"sender_item_id\":\"item_" . time() . "\"}]}",
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Authorization: Bearer $access_token"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$payout = json_decode($response);
if ($payout->batch_header->batch_status == "SUCCESS") {
echo "Payout sent successfully!";
} else {
echo "Payout failed: " . $payout->batch_header->failure_reason;
}
}
}
To have your app receive notifications when the Payout was completed you can subscribe to the PAYMENT.PAYOUTSBATCH.SUCCESS Webhook.
Here is a sample of a script that would subcribe that webhook:
<?php
$paypal_client_id = "your_client_id";
$paypal_secret = "your_secret";
$webhook_url = "https://www.example.com/webhooks/payouts_success";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paypal.com/v1/oauth2/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "grant_type=client_credentials",
CURLOPT_HTTPHEADER => array(
"Authorization: Basic " . base64_encode("$paypal_client_id:$paypal_secret"),
"Content-Type: application/x-www-form-urlencoded"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$access_token = json_decode($response)->access_token;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paypal.com/v1/notifications/webhooks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"url\":\"$webhook_url\",\"event_types\":[{\"name\":\"PAYMENT.PAYOUTSBATCH.SUCCESS\"}]}",
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Authorization: Bearer $access_token"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
$webhook = json_decode($response);
if ($webhook->name == "PAYMENT.PAYOUTSBATCH.SUCCESS") {
echo "Webhook subscribed successfully!";
} else {
echo "Webhook subscription failed: " . $webhook->name;
}
}
}
Then you would setup a webhook handler at the webhook URL you provided. Here is an example of how that might look:
<?php
$webhook_data = json_decode(file_get_contents('php://input'), true);
if ($webhook_data["event_type"] == "PAYMENT.PAYOUTSBATCH.SUCCESS") {
// handle the payout success event
$batch_id = $webhook_data["resource"]["batch_header"]["payout_batch_id"];
$status = $webhook_data["resource"]["batch_header"]["batch_status"];
// log the batch ID and status for reference
error_log("Batch ID: $batch_id");
error_log("Status: $status");
// process the successful payout
// ...
} else {
// handle other event types
// ...
}

Getting always INVALID_RESOURCE_ID when executing paypal payment through rest api

Please Help!
When executing paypal approved payment i am always getting below JSON response which is quite frustrating me :(
{
"name": "INVALID_RESOURCE_ID",
"message": "Requested resource ID was not found.",
"information_link": "https://developer.paypal.com/webapps/developer/docs/api/#INVALID_RESOURCE_ID",
"debug_id": "a09bc8e96fc48"
}
Here's my code for papal api request which is same as paypal documentation
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.sandbox.paypal.com/v1/payments/payment/PAY-18X32451H0459092JKO7KFUI/execute",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"payer_id\": \"<Some id here>\"}",
CURLOPT_HTTPHEADER => array(
"authorization: Bearer A101.gMSMRy4uGwjHLcnY4mbzRXLkm9ct0wfPl2M5sV82B3rO01L_ipJHyA65kbIg8kz9.2_AHXRp5zZaZSEfqz-P3x8eai9y",
"cache-control: no-cache",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Please help.